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

Side by Side Diff: src/deoptimizer.h

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' 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/debug-debugger.js ('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 MemoryChunk* eager_deoptimization_entry_code_; 89 MemoryChunk* eager_deoptimization_entry_code_;
86 MemoryChunk* lazy_deoptimization_entry_code_; 90 MemoryChunk* 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 186
166 // Change all patched stack guard checks in the unoptimized code 187 // Change all patched stack guard checks in the unoptimized code
167 // back to a normal stack guard check. 188 // back to a normal stack guard check.
168 static void RevertStackCheckCodeAt(Address pc_after, 189 static void RevertStackCheckCodeAt(Address pc_after,
169 Code* check_code, 190 Code* check_code,
170 Code* replacement_code); 191 Code* replacement_code);
171 192
172 ~Deoptimizer(); 193 ~Deoptimizer();
173 194
174 void MaterializeHeapNumbers(); 195 void MaterializeHeapNumbers();
196 #ifdef ENABLE_DEBUGGER_SUPPORT
197 void MaterializeHeapNumbersForDebuggerInspectableFrame(
198 Address top, uint32_t size, DeoptimizedFrameInfo* info);
199 #endif
175 200
176 static void ComputeOutputFrames(Deoptimizer* deoptimizer); 201 static void ComputeOutputFrames(Deoptimizer* deoptimizer);
177 202
178 static Address GetDeoptimizationEntry(int id, BailoutType type); 203 static Address GetDeoptimizationEntry(int id, BailoutType type);
179 static int GetDeoptimizationId(Address addr, BailoutType type); 204 static int GetDeoptimizationId(Address addr, BailoutType type);
180 static int GetOutputInfo(DeoptimizationOutputData* data, 205 static int GetOutputInfo(DeoptimizationOutputData* data,
181 unsigned node_id, 206 unsigned node_id,
182 SharedFunctionInfo* shared); 207 SharedFunctionInfo* shared);
183 208
184 // Code generation support. 209 // Code generation support.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 }; 252 };
228 253
229 private: 254 private:
230 static const int kNumberOfEntries = 4096; 255 static const int kNumberOfEntries = 4096;
231 256
232 Deoptimizer(Isolate* isolate, 257 Deoptimizer(Isolate* isolate,
233 JSFunction* function, 258 JSFunction* function,
234 BailoutType type, 259 BailoutType type,
235 unsigned bailout_id, 260 unsigned bailout_id,
236 Address from, 261 Address from,
237 int fp_to_sp_delta); 262 int fp_to_sp_delta,
263 Code* optimized_code);
238 void DeleteFrameDescriptions(); 264 void DeleteFrameDescriptions();
239 265
240 void DoComputeOutputFrames(); 266 void DoComputeOutputFrames();
241 void DoComputeOsrOutputFrame(); 267 void DoComputeOsrOutputFrame();
242 void DoComputeFrame(TranslationIterator* iterator, int frame_index); 268 void DoComputeFrame(TranslationIterator* iterator, int frame_index);
243 void DoTranslateCommand(TranslationIterator* iterator, 269 void DoTranslateCommand(TranslationIterator* iterator,
244 int frame_index, 270 int frame_index,
245 unsigned output_offset); 271 unsigned output_offset);
246 // Translate a command for OSR. Updates the input offset to be used for 272 // Translate a command for OSR. Updates the input offset to be used for
247 // the next command. Returns false if translation of the command failed 273 // the next command. Returns false if translation of the command failed
(...skipping 15 matching lines...) Expand all
263 static MemoryChunk* CreateCode(BailoutType type); 289 static MemoryChunk* CreateCode(BailoutType type);
264 static void GenerateDeoptimizationEntries( 290 static void GenerateDeoptimizationEntries(
265 MacroAssembler* masm, int count, BailoutType type); 291 MacroAssembler* masm, int count, BailoutType type);
266 292
267 // Weak handle callback for deoptimizing code objects. 293 // Weak handle callback for deoptimizing code objects.
268 static void HandleWeakDeoptimizedCode( 294 static void HandleWeakDeoptimizedCode(
269 v8::Persistent<v8::Value> obj, void* data); 295 v8::Persistent<v8::Value> obj, void* data);
270 static Code* FindDeoptimizingCodeFromAddress(Address addr); 296 static Code* FindDeoptimizingCodeFromAddress(Address addr);
271 static void RemoveDeoptimizingCode(Code* code); 297 static void RemoveDeoptimizingCode(Code* code);
272 298
299 // Fill the input from from a JavaScript frame. This is used when
300 // the debugger needs to inspect an optimized frame. For normal
301 // deoptimizations the input frame is filled in generated code.
302 void FillInputFrame(Address tos, JavaScriptFrame* frame);
303
273 Isolate* isolate_; 304 Isolate* isolate_;
274 JSFunction* function_; 305 JSFunction* function_;
275 Code* optimized_code_; 306 Code* optimized_code_;
276 unsigned bailout_id_; 307 unsigned bailout_id_;
277 BailoutType bailout_type_; 308 BailoutType bailout_type_;
278 Address from_; 309 Address from_;
279 int fp_to_sp_delta_; 310 int fp_to_sp_delta_;
280 311
281 // Input frame description. 312 // Input frame description.
282 FrameDescription* input_; 313 FrameDescription* input_;
283 // Number of output frames. 314 // Number of output frames.
284 int output_count_; 315 int output_count_;
285 // Array of output frame descriptions. 316 // Array of output frame descriptions.
286 FrameDescription** output_; 317 FrameDescription** output_;
287 318
288 List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_; 319 List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_;
289 320
290 static int table_entry_size_; 321 static int table_entry_size_;
291 322
292 friend class FrameDescription; 323 friend class FrameDescription;
293 friend class DeoptimizingCodeListNode; 324 friend class DeoptimizingCodeListNode;
325 friend class DeoptimizedFrameInfo;
294 }; 326 };
295 327
296 328
297 class FrameDescription { 329 class FrameDescription {
298 public: 330 public:
299 FrameDescription(uint32_t frame_size, 331 FrameDescription(uint32_t frame_size,
300 JSFunction* function); 332 JSFunction* function);
301 333
302 void* operator new(size_t size, uint32_t frame_size) { 334 void* operator new(size_t size, uint32_t frame_size) {
303 // Subtracts kPointerSize, as the member frame_content_ already supplies 335 // Subtracts kPointerSize, as the member frame_content_ already supplies
304 // the first element of the area to store the frame. 336 // the first element of the area to store the frame.
305 return malloc(size + frame_size - kPointerSize); 337 return malloc(size + frame_size - kPointerSize);
306 } 338 }
307 339
308 void operator delete(void* description) { 340 void operator delete(void* description) {
309 free(description); 341 free(description);
310 } 342 }
311 343
312 intptr_t GetFrameSize() const { return frame_size_; } 344 uint32_t GetFrameSize() const {
345 ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_);
346 return static_cast<uint32_t>(frame_size_);
347 }
313 348
314 JSFunction* GetFunction() const { return function_; } 349 JSFunction* GetFunction() const { return function_; }
315 350
316 unsigned GetOffsetFromSlotIndex(Deoptimizer* deoptimizer, int slot_index); 351 unsigned GetOffsetFromSlotIndex(Deoptimizer* deoptimizer, int slot_index);
317 352
318 intptr_t GetFrameSlot(unsigned offset) { 353 intptr_t GetFrameSlot(unsigned offset) {
319 return *GetFrameSlotPointer(offset); 354 return *GetFrameSlotPointer(offset);
320 } 355 }
321 356
322 double GetDoubleFrameSlot(unsigned offset) { 357 double GetDoubleFrameSlot(unsigned offset) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 void SetPc(intptr_t pc) { pc_ = pc; } 389 void SetPc(intptr_t pc) { pc_ = pc; }
355 390
356 intptr_t GetFp() const { return fp_; } 391 intptr_t GetFp() const { return fp_; }
357 void SetFp(intptr_t fp) { fp_ = fp; } 392 void SetFp(intptr_t fp) { fp_ = fp; }
358 393
359 Smi* GetState() const { return state_; } 394 Smi* GetState() const { return state_; }
360 void SetState(Smi* state) { state_ = state; } 395 void SetState(Smi* state) { state_ = state; }
361 396
362 void SetContinuation(intptr_t pc) { continuation_ = pc; } 397 void SetContinuation(intptr_t pc) { continuation_ = pc; }
363 398
399 #ifdef DEBUG
400 Code::Kind GetKind() const { return kind_; }
401 void SetKind(Code::Kind kind) { kind_ = kind; }
402 #endif
403
404 // Get the incoming arguments count.
405 int ComputeParametersCount();
406
407 // Get a parameter value for an unoptimized frame.
408 Object* GetParameter(Deoptimizer* deoptimizer, int index);
409
410 // Get the expression stack height for a unoptimized frame.
411 unsigned GetExpressionCount(Deoptimizer* deoptimizer);
412
413 // Get the expression stack value for an unoptimized frame.
414 Object* GetExpression(Deoptimizer* deoptimizer, int index);
415
364 static int registers_offset() { 416 static int registers_offset() {
365 return OFFSET_OF(FrameDescription, registers_); 417 return OFFSET_OF(FrameDescription, registers_);
366 } 418 }
367 419
368 static int double_registers_offset() { 420 static int double_registers_offset() {
369 return OFFSET_OF(FrameDescription, double_registers_); 421 return OFFSET_OF(FrameDescription, double_registers_);
370 } 422 }
371 423
372 static int frame_size_offset() { 424 static int frame_size_offset() {
373 return OFFSET_OF(FrameDescription, frame_size_); 425 return OFFSET_OF(FrameDescription, frame_size_);
(...skipping 11 matching lines...) Expand all
385 return OFFSET_OF(FrameDescription, continuation_); 437 return OFFSET_OF(FrameDescription, continuation_);
386 } 438 }
387 439
388 static int frame_content_offset() { 440 static int frame_content_offset() {
389 return OFFSET_OF(FrameDescription, frame_content_); 441 return OFFSET_OF(FrameDescription, frame_content_);
390 } 442 }
391 443
392 private: 444 private:
393 static const uint32_t kZapUint32 = 0xbeeddead; 445 static const uint32_t kZapUint32 = 0xbeeddead;
394 446
447 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to
448 // keep the variable-size array frame_content_ of type intptr_t at
449 // the end of the structure aligned.
395 uintptr_t frame_size_; // Number of bytes. 450 uintptr_t frame_size_; // Number of bytes.
396 JSFunction* function_; 451 JSFunction* function_;
397 intptr_t registers_[Register::kNumRegisters]; 452 intptr_t registers_[Register::kNumRegisters];
398 double double_registers_[DoubleRegister::kNumAllocatableRegisters]; 453 double double_registers_[DoubleRegister::kNumAllocatableRegisters];
399 intptr_t top_; 454 intptr_t top_;
400 intptr_t pc_; 455 intptr_t pc_;
401 intptr_t fp_; 456 intptr_t fp_;
402 Smi* state_; 457 Smi* state_;
458 #ifdef DEBUG
459 Code::Kind kind_;
460 #endif
403 461
404 // Continuation is the PC where the execution continues after 462 // Continuation is the PC where the execution continues after
405 // deoptimizing. 463 // deoptimizing.
406 intptr_t continuation_; 464 intptr_t continuation_;
407 465
408 // This must be at the end of the object as the object is allocated larger 466 // This must be at the end of the object as the object is allocated larger
409 // than it's definition indicate to extend this array. 467 // than it's definition indicate to extend this array.
410 intptr_t frame_content_[1]; 468 intptr_t frame_content_[1];
411 469
412 intptr_t* GetFrameSlotPointer(unsigned offset) { 470 intptr_t* GetFrameSlotPointer(unsigned offset) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 void StoreDoubleRegister(DoubleRegister reg); 547 void StoreDoubleRegister(DoubleRegister reg);
490 void StoreStackSlot(int index); 548 void StoreStackSlot(int index);
491 void StoreInt32StackSlot(int index); 549 void StoreInt32StackSlot(int index);
492 void StoreDoubleStackSlot(int index); 550 void StoreDoubleStackSlot(int index);
493 void StoreLiteral(int literal_id); 551 void StoreLiteral(int literal_id);
494 void StoreArgumentsObject(); 552 void StoreArgumentsObject();
495 void MarkDuplicate(); 553 void MarkDuplicate();
496 554
497 static int NumberOfOperandsFor(Opcode opcode); 555 static int NumberOfOperandsFor(Opcode opcode);
498 556
499 #ifdef OBJECT_PRINT 557 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
500 static const char* StringFor(Opcode opcode); 558 static const char* StringFor(Opcode opcode);
501 #endif 559 #endif
502 560
503 private: 561 private:
504 TranslationBuffer* buffer_; 562 TranslationBuffer* buffer_;
505 int index_; 563 int index_;
506 }; 564 };
507 565
508 566
509 // Linked list holding deoptimizing code objects. The deoptimizing code objects 567 // Linked list holding deoptimizing code objects. The deoptimizing code objects
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 return frame->fp() + offset - ((slot_index + 1) * kPointerSize); 649 return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
592 } 650 }
593 } 651 }
594 652
595 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator, 653 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator,
596 DeoptimizationInputData* data, 654 DeoptimizationInputData* data,
597 JavaScriptFrame* frame); 655 JavaScriptFrame* frame);
598 }; 656 };
599 657
600 658
659 #ifdef ENABLE_DEBUGGER_SUPPORT
660 // Class used to represent an unoptimized frame when the debugger
661 // needs to inspect a frame that is part of an optimized frame. The
662 // internally used FrameDescription objects are not GC safe so for use
663 // by the debugger frame information is copied to an object of this type.
664 class DeoptimizedFrameInfo : public Malloced {
665 public:
666 DeoptimizedFrameInfo(Deoptimizer* deoptimizer, int frame_index);
667 virtual ~DeoptimizedFrameInfo();
668
669 // GC support.
670 void Iterate(ObjectVisitor* v);
671
672 // Return the number of incoming arguments.
673 int parameters_count() { return parameters_count_; }
674
675 // Return the height of the expression stack.
676 int expression_count() { return expression_count_; }
677
678 // Get the frame function.
679 JSFunction* GetFunction() {
680 return function_;
681 }
682
683 // Get an incoming argument.
684 Object* GetParameter(int index) {
685 ASSERT(0 <= index && index < parameters_count());
686 return parameters_[index];
687 }
688
689 // Get an expression from the expression stack.
690 Object* GetExpression(int index) {
691 ASSERT(0 <= index && index < expression_count());
692 return expression_stack_[index];
693 }
694
695 private:
696 // Set the frame function.
697 void SetFunction(JSFunction* function) {
698 function_ = function;
699 }
700
701 // Set an incoming argument.
702 void SetParameter(int index, Object* obj) {
703 ASSERT(0 <= index && index < parameters_count());
704 parameters_[index] = obj;
705 }
706
707 // Set an expression on the expression stack.
708 void SetExpression(int index, Object* obj) {
709 ASSERT(0 <= index && index < expression_count());
710 expression_stack_[index] = obj;
711 }
712
713 JSFunction* function_;
714 int parameters_count_;
715 int expression_count_;
716 Object** parameters_;
717 Object** expression_stack_;
718
719 friend class Deoptimizer;
720 };
721 #endif
722
601 } } // namespace v8::internal 723 } } // namespace v8::internal
602 724
603 #endif // V8_DEOPTIMIZER_H_ 725 #endif // V8_DEOPTIMIZER_H_
OLDNEW
« no previous file with comments | « src/debug-debugger.js ('k') | src/deoptimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698