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

Side by Side Diff: src/deoptimizer.h

Issue 9265004: Support inlining at call-sites with mismatched number of arguments. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: finished implementation, extended tests, ported to x64&arm Created 8 years, 11 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 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
11 // with the distribution. 11 // with the distribution.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 EAGER, 112 EAGER,
113 LAZY, 113 LAZY,
114 OSR, 114 OSR,
115 // This last bailout type is not really a bailout, but used by the 115 // This last bailout type is not really a bailout, but used by the
116 // debugger to deoptimize stack frames to allow inspection. 116 // debugger to deoptimize stack frames to allow inspection.
117 DEBUGGER 117 DEBUGGER
118 }; 118 };
119 119
120 int output_count() const { return output_count_; } 120 int output_count() const { return output_count_; }
121 121
122 // Number of created JS frames. Not all created frames are necessarily JS.
123 int jsframe_count() const { return jsframe_count_; }
124
122 static Deoptimizer* New(JSFunction* function, 125 static Deoptimizer* New(JSFunction* function,
123 BailoutType type, 126 BailoutType type,
124 unsigned bailout_id, 127 unsigned bailout_id,
125 Address from, 128 Address from,
126 int fp_to_sp_delta, 129 int fp_to_sp_delta,
127 Isolate* isolate); 130 Isolate* isolate);
128 static Deoptimizer* Grab(Isolate* isolate); 131 static Deoptimizer* Grab(Isolate* isolate);
129 132
130 #ifdef ENABLE_DEBUGGER_SUPPORT 133 #ifdef ENABLE_DEBUGGER_SUPPORT
131 // The returned object with information on the optimized frame needs to be 134 // The returned object with information on the optimized frame needs to be
132 // freed before another one can be generated. 135 // freed before another one can be generated.
133 static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame, 136 static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame,
134 int frame_index, 137 int jsframe_index,
135 Isolate* isolate); 138 Isolate* isolate);
136 static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info, 139 static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
137 Isolate* isolate); 140 Isolate* isolate);
138 #endif 141 #endif
139 142
140 // Makes sure that there is enough room in the relocation 143 // Makes sure that there is enough room in the relocation
141 // information of a code object to perform lazy deoptimization 144 // information of a code object to perform lazy deoptimization
142 // patching. If there is not enough room a new relocation 145 // patching. If there is not enough room a new relocation
143 // information object is allocated and comments are added until it 146 // information object is allocated and comments are added until it
144 // is big enough. 147 // is big enough.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 static void RevertStackCheckCodeAt(Code* unoptimized_code, 192 static void RevertStackCheckCodeAt(Code* unoptimized_code,
190 Address pc_after, 193 Address pc_after,
191 Code* check_code, 194 Code* check_code,
192 Code* replacement_code); 195 Code* replacement_code);
193 196
194 ~Deoptimizer(); 197 ~Deoptimizer();
195 198
196 void MaterializeHeapNumbers(); 199 void MaterializeHeapNumbers();
197 #ifdef ENABLE_DEBUGGER_SUPPORT 200 #ifdef ENABLE_DEBUGGER_SUPPORT
198 void MaterializeHeapNumbersForDebuggerInspectableFrame( 201 void MaterializeHeapNumbersForDebuggerInspectableFrame(
199 Address top, uint32_t size, DeoptimizedFrameInfo* info); 202 Address parameters_top,
203 uint32_t parameters_size,
204 Address expressions_top,
205 uint32_t expressions_size,
206 DeoptimizedFrameInfo* info);
200 #endif 207 #endif
201 208
202 static void ComputeOutputFrames(Deoptimizer* deoptimizer); 209 static void ComputeOutputFrames(Deoptimizer* deoptimizer);
203 210
204 static Address GetDeoptimizationEntry(int id, BailoutType type); 211 static Address GetDeoptimizationEntry(int id, BailoutType type);
205 static int GetDeoptimizationId(Address addr, BailoutType type); 212 static int GetDeoptimizationId(Address addr, BailoutType type);
206 static int GetOutputInfo(DeoptimizationOutputData* data, 213 static int GetOutputInfo(DeoptimizationOutputData* data,
207 unsigned node_id, 214 unsigned node_id,
208 SharedFunctionInfo* shared); 215 SharedFunctionInfo* shared);
209 216
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 257
251 protected: 258 protected:
252 virtual void GeneratePrologue(); 259 virtual void GeneratePrologue();
253 260
254 private: 261 private:
255 int count() const { return count_; } 262 int count() const { return count_; }
256 263
257 int count_; 264 int count_;
258 }; 265 };
259 266
267 int ConvertJSFrameIndexToFrameIndex(int jsframe_index);
268
260 private: 269 private:
261 static const int kNumberOfEntries = 4096; 270 static const int kNumberOfEntries = 4096;
262 271
263 Deoptimizer(Isolate* isolate, 272 Deoptimizer(Isolate* isolate,
264 JSFunction* function, 273 JSFunction* function,
265 BailoutType type, 274 BailoutType type,
266 unsigned bailout_id, 275 unsigned bailout_id,
267 Address from, 276 Address from,
268 int fp_to_sp_delta, 277 int fp_to_sp_delta,
269 Code* optimized_code); 278 Code* optimized_code);
270 void DeleteFrameDescriptions(); 279 void DeleteFrameDescriptions();
271 280
272 void DoComputeOutputFrames(); 281 void DoComputeOutputFrames();
273 void DoComputeOsrOutputFrame(); 282 void DoComputeOsrOutputFrame();
274 void DoComputeFrame(TranslationIterator* iterator, int frame_index); 283 void DoComputeJSFrame(TranslationIterator* iterator, int frame_index);
284 void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
285 int frame_index);
275 void DoTranslateCommand(TranslationIterator* iterator, 286 void DoTranslateCommand(TranslationIterator* iterator,
276 int frame_index, 287 int frame_index,
277 unsigned output_offset); 288 unsigned output_offset);
278 // Translate a command for OSR. Updates the input offset to be used for 289 // Translate a command for OSR. Updates the input offset to be used for
279 // the next command. Returns false if translation of the command failed 290 // the next command. Returns false if translation of the command failed
280 // (e.g., a number conversion failed) and may or may not have updated the 291 // (e.g., a number conversion failed) and may or may not have updated the
281 // input offset. 292 // input offset.
282 bool DoOsrTranslateCommand(TranslationIterator* iterator, 293 bool DoOsrTranslateCommand(TranslationIterator* iterator,
283 int* input_offset); 294 int* input_offset);
284 295
(...skipping 27 matching lines...) Expand all
312 Code* optimized_code_; 323 Code* optimized_code_;
313 unsigned bailout_id_; 324 unsigned bailout_id_;
314 BailoutType bailout_type_; 325 BailoutType bailout_type_;
315 Address from_; 326 Address from_;
316 int fp_to_sp_delta_; 327 int fp_to_sp_delta_;
317 328
318 // Input frame description. 329 // Input frame description.
319 FrameDescription* input_; 330 FrameDescription* input_;
320 // Number of output frames. 331 // Number of output frames.
321 int output_count_; 332 int output_count_;
333 // Number of output js frames.
334 int jsframe_count_;
322 // Array of output frame descriptions. 335 // Array of output frame descriptions.
323 FrameDescription** output_; 336 FrameDescription** output_;
324 337
325 // Frames can be dynamically padded on ia32 to align untagged doubles. 338 // Frames can be dynamically padded on ia32 to align untagged doubles.
326 Object* frame_alignment_marker_; 339 Object* frame_alignment_marker_;
327 intptr_t has_alignment_padding_; 340 intptr_t has_alignment_padding_;
328 341
329 List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_; 342 List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_;
330 343
331 static const int table_entry_size_; 344 static const int table_entry_size_;
(...skipping 23 matching lines...) Expand all
355 free(description); 368 free(description);
356 } 369 }
357 370
358 uint32_t GetFrameSize() const { 371 uint32_t GetFrameSize() const {
359 ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_); 372 ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_);
360 return static_cast<uint32_t>(frame_size_); 373 return static_cast<uint32_t>(frame_size_);
361 } 374 }
362 375
363 JSFunction* GetFunction() const { return function_; } 376 JSFunction* GetFunction() const { return function_; }
364 377
365 unsigned GetOffsetFromSlotIndex(Deoptimizer* deoptimizer, int slot_index); 378 unsigned GetOffsetFromSlotIndex(int slot_index);
366 379
367 intptr_t GetFrameSlot(unsigned offset) { 380 intptr_t GetFrameSlot(unsigned offset) {
368 return *GetFrameSlotPointer(offset); 381 return *GetFrameSlotPointer(offset);
369 } 382 }
370 383
371 double GetDoubleFrameSlot(unsigned offset) { 384 double GetDoubleFrameSlot(unsigned offset) {
372 intptr_t* ptr = GetFrameSlotPointer(offset); 385 intptr_t* ptr = GetFrameSlotPointer(offset);
373 #if V8_TARGET_ARCH_MIPS 386 #if V8_TARGET_ARCH_MIPS
374 // Prevent gcc from using load-double (mips ldc1) on (possibly) 387 // Prevent gcc from using load-double (mips ldc1) on (possibly)
375 // non-64-bit aligned double. Uses two lwc1 instructions. 388 // non-64-bit aligned double. Uses two lwc1 instructions.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 void SetPc(intptr_t pc) { pc_ = pc; } 429 void SetPc(intptr_t pc) { pc_ = pc; }
417 430
418 intptr_t GetFp() const { return fp_; } 431 intptr_t GetFp() const { return fp_; }
419 void SetFp(intptr_t fp) { fp_ = fp; } 432 void SetFp(intptr_t fp) { fp_ = fp; }
420 433
421 Smi* GetState() const { return state_; } 434 Smi* GetState() const { return state_; }
422 void SetState(Smi* state) { state_ = state; } 435 void SetState(Smi* state) { state_ = state; }
423 436
424 void SetContinuation(intptr_t pc) { continuation_ = pc; } 437 void SetContinuation(intptr_t pc) { continuation_ = pc; }
425 438
439 StackFrame::Type GetType() const { return type_; }
Kevin Millikin (Chromium) 2012/01/24 00:08:54 Type and Kind are too generic (kind was before).
Vyacheslav Egorov (Chromium) 2012/01/24 08:49:20 Done.
440 void SetType(StackFrame::Type type) { type_ = type; }
441
426 #ifdef DEBUG 442 #ifdef DEBUG
427 Code::Kind GetKind() const { return kind_; } 443 Code::Kind GetKind() const { return kind_; }
428 void SetKind(Code::Kind kind) { kind_ = kind; } 444 void SetKind(Code::Kind kind) { kind_ = kind; }
429 #endif 445 #endif
430 446
431 // Get the incoming arguments count. 447 // Get the incoming arguments count.
432 int ComputeParametersCount(); 448 int ComputeParametersCount();
433 449
434 // Get a parameter value for an unoptimized frame. 450 // Get a parameter value for an unoptimized frame.
435 Object* GetParameter(Deoptimizer* deoptimizer, int index); 451 Object* GetParameter(int index);
436 452
437 // Get the expression stack height for a unoptimized frame. 453 // Get the expression stack height for a unoptimized frame.
438 unsigned GetExpressionCount(Deoptimizer* deoptimizer); 454 unsigned GetExpressionCount();
439 455
440 // Get the expression stack value for an unoptimized frame. 456 // Get the expression stack value for an unoptimized frame.
441 Object* GetExpression(Deoptimizer* deoptimizer, int index); 457 Object* GetExpression(int index);
442 458
443 static int registers_offset() { 459 static int registers_offset() {
444 return OFFSET_OF(FrameDescription, registers_); 460 return OFFSET_OF(FrameDescription, registers_);
445 } 461 }
446 462
447 static int double_registers_offset() { 463 static int double_registers_offset() {
448 return OFFSET_OF(FrameDescription, double_registers_); 464 return OFFSET_OF(FrameDescription, double_registers_);
449 } 465 }
450 466
451 static int frame_size_offset() { 467 static int frame_size_offset() {
(...skipping 22 matching lines...) Expand all
474 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to 490 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to
475 // keep the variable-size array frame_content_ of type intptr_t at 491 // keep the variable-size array frame_content_ of type intptr_t at
476 // the end of the structure aligned. 492 // the end of the structure aligned.
477 uintptr_t frame_size_; // Number of bytes. 493 uintptr_t frame_size_; // Number of bytes.
478 JSFunction* function_; 494 JSFunction* function_;
479 intptr_t registers_[Register::kNumRegisters]; 495 intptr_t registers_[Register::kNumRegisters];
480 double double_registers_[DoubleRegister::kNumAllocatableRegisters]; 496 double double_registers_[DoubleRegister::kNumAllocatableRegisters];
481 intptr_t top_; 497 intptr_t top_;
482 intptr_t pc_; 498 intptr_t pc_;
483 intptr_t fp_; 499 intptr_t fp_;
500 StackFrame::Type type_;
484 Smi* state_; 501 Smi* state_;
485 #ifdef DEBUG 502 #ifdef DEBUG
486 Code::Kind kind_; 503 Code::Kind kind_;
487 #endif 504 #endif
488 505
489 // Continuation is the PC where the execution continues after 506 // Continuation is the PC where the execution continues after
490 // deoptimizing. 507 // deoptimizing.
491 intptr_t continuation_; 508 intptr_t continuation_;
492 509
493 // This must be at the end of the object as the object is allocated larger 510 // This must be at the end of the object as the object is allocated larger
494 // than it's definition indicate to extend this array. 511 // than it's definition indicate to extend this array.
495 intptr_t frame_content_[1]; 512 intptr_t frame_content_[1];
496 513
497 intptr_t* GetFrameSlotPointer(unsigned offset) { 514 intptr_t* GetFrameSlotPointer(unsigned offset) {
498 ASSERT(offset < frame_size_); 515 ASSERT(offset < frame_size_);
499 return reinterpret_cast<intptr_t*>( 516 return reinterpret_cast<intptr_t*>(
500 reinterpret_cast<Address>(this) + frame_content_offset() + offset); 517 reinterpret_cast<Address>(this) + frame_content_offset() + offset);
501 } 518 }
519
520 int ComputeFixedSize();
502 }; 521 };
503 522
504 523
505 class TranslationBuffer BASE_EMBEDDED { 524 class TranslationBuffer BASE_EMBEDDED {
506 public: 525 public:
507 TranslationBuffer() : contents_(256) { } 526 TranslationBuffer() : contents_(256) { }
508 527
509 int CurrentIndex() const { return contents_.length(); } 528 int CurrentIndex() const { return contents_.length(); }
510 void Add(int32_t value); 529 void Add(int32_t value);
511 530
(...skipping 22 matching lines...) Expand all
534 private: 553 private:
535 ByteArray* buffer_; 554 ByteArray* buffer_;
536 int index_; 555 int index_;
537 }; 556 };
538 557
539 558
540 class Translation BASE_EMBEDDED { 559 class Translation BASE_EMBEDDED {
541 public: 560 public:
542 enum Opcode { 561 enum Opcode {
543 BEGIN, 562 BEGIN,
544 FRAME, 563 JS_FRAME,
564 ARGUMENTS_ADAPTOR_FRAME,
545 REGISTER, 565 REGISTER,
546 INT32_REGISTER, 566 INT32_REGISTER,
547 DOUBLE_REGISTER, 567 DOUBLE_REGISTER,
548 STACK_SLOT, 568 STACK_SLOT,
549 INT32_STACK_SLOT, 569 INT32_STACK_SLOT,
550 DOUBLE_STACK_SLOT, 570 DOUBLE_STACK_SLOT,
551 LITERAL, 571 LITERAL,
552 ARGUMENTS_OBJECT, 572 ARGUMENTS_OBJECT,
553 573
554 // A prefix indicating that the next command is a duplicate of the one 574 // A prefix indicating that the next command is a duplicate of the one
555 // that follows it. 575 // that follows it.
556 DUPLICATE 576 DUPLICATE
557 }; 577 };
558 578
559 Translation(TranslationBuffer* buffer, int frame_count) 579 Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count)
560 : buffer_(buffer), 580 : buffer_(buffer),
561 index_(buffer->CurrentIndex()) { 581 index_(buffer->CurrentIndex()) {
562 buffer_->Add(BEGIN); 582 buffer_->Add(BEGIN);
563 buffer_->Add(frame_count); 583 buffer_->Add(frame_count);
584 buffer_->Add(jsframe_count);
564 } 585 }
565 586
566 int index() const { return index_; } 587 int index() const { return index_; }
567 588
568 // Commands. 589 // Commands.
569 void BeginFrame(int node_id, int literal_id, unsigned height); 590 void BeginJSFrame(int node_id, int literal_id, unsigned height);
591 void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
570 void StoreRegister(Register reg); 592 void StoreRegister(Register reg);
571 void StoreInt32Register(Register reg); 593 void StoreInt32Register(Register reg);
572 void StoreDoubleRegister(DoubleRegister reg); 594 void StoreDoubleRegister(DoubleRegister reg);
573 void StoreStackSlot(int index); 595 void StoreStackSlot(int index);
574 void StoreInt32StackSlot(int index); 596 void StoreInt32StackSlot(int index);
575 void StoreDoubleStackSlot(int index); 597 void StoreDoubleStackSlot(int index);
576 void StoreLiteral(int literal_id); 598 void StoreLiteral(int literal_id);
577 void StoreArgumentsObject(); 599 void StoreArgumentsObject();
578 void MarkDuplicate(); 600 void MarkDuplicate();
579 601
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 671
650 case LITERAL: 672 case LITERAL:
651 return literal_; 673 return literal_;
652 674
653 default: 675 default:
654 UNREACHABLE(); 676 UNREACHABLE();
655 return Handle<Object>::null(); 677 return Handle<Object>::null();
656 } 678 }
657 } 679 }
658 680
659 static void ComputeSlotMappingForArguments(JavaScriptFrame* frame, 681 static Vector<SlotRef> ComputeSlotMappingForArguments(
660 int inlined_frame_index, 682 JavaScriptFrame* frame,
661 Vector<SlotRef>* args_slots); 683 int inlined_frame_index,
684 int formal_parameter_count);
662 685
663 private: 686 private:
664 Address addr_; 687 Address addr_;
665 Handle<Object> literal_; 688 Handle<Object> literal_;
666 SlotRepresentation representation_; 689 SlotRepresentation representation_;
667 690
668 static Address SlotAddress(JavaScriptFrame* frame, int slot_index) { 691 static Address SlotAddress(JavaScriptFrame* frame, int slot_index) {
669 if (slot_index >= 0) { 692 if (slot_index >= 0) {
670 const int offset = JavaScriptFrameConstants::kLocal0Offset; 693 const int offset = JavaScriptFrameConstants::kLocal0Offset;
671 return frame->fp() + offset - (slot_index * kPointerSize); 694 return frame->fp() + offset - (slot_index * kPointerSize);
672 } else { 695 } else {
673 const int offset = JavaScriptFrameConstants::kLastParameterOffset; 696 const int offset = JavaScriptFrameConstants::kLastParameterOffset;
674 return frame->fp() + offset - ((slot_index + 1) * kPointerSize); 697 return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
675 } 698 }
676 } 699 }
677 700
678 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator, 701 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator,
679 DeoptimizationInputData* data, 702 DeoptimizationInputData* data,
680 JavaScriptFrame* frame); 703 JavaScriptFrame* frame);
704
705 static void ComputeSlotsForArguments(
706 Vector<SlotRef>* args_slots,
707 TranslationIterator* iterator,
708 DeoptimizationInputData* data,
709 JavaScriptFrame* frame);
681 }; 710 };
682 711
683 712
684 #ifdef ENABLE_DEBUGGER_SUPPORT 713 #ifdef ENABLE_DEBUGGER_SUPPORT
685 // Class used to represent an unoptimized frame when the debugger 714 // Class used to represent an unoptimized frame when the debugger
686 // needs to inspect a frame that is part of an optimized frame. The 715 // needs to inspect a frame that is part of an optimized frame. The
687 // internally used FrameDescription objects are not GC safe so for use 716 // internally used FrameDescription objects are not GC safe so for use
688 // by the debugger frame information is copied to an object of this type. 717 // by the debugger frame information is copied to an object of this type.
718 // Represents parameters in unadapted form so their number might mismatch
719 // formal parameter count.
689 class DeoptimizedFrameInfo : public Malloced { 720 class DeoptimizedFrameInfo : public Malloced {
690 public: 721 public:
691 DeoptimizedFrameInfo(Deoptimizer* deoptimizer, int frame_index); 722 DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
723 int frame_index,
724 bool has_arguments_adaptor);
692 virtual ~DeoptimizedFrameInfo(); 725 virtual ~DeoptimizedFrameInfo();
693 726
694 // GC support. 727 // GC support.
695 void Iterate(ObjectVisitor* v); 728 void Iterate(ObjectVisitor* v);
696 729
697 // Return the number of incoming arguments. 730 // Return the number of incoming arguments.
698 int parameters_count() { return parameters_count_; } 731 int parameters_count() { return parameters_count_; }
699 732
700 // Return the height of the expression stack. 733 // Return the height of the expression stack.
701 int expression_count() { return expression_count_; } 734 int expression_count() { return expression_count_; }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 Object** parameters_; 774 Object** parameters_;
742 Object** expression_stack_; 775 Object** expression_stack_;
743 776
744 friend class Deoptimizer; 777 friend class Deoptimizer;
745 }; 778 };
746 #endif 779 #endif
747 780
748 } } // namespace v8::internal 781 } } // namespace v8::internal
749 782
750 #endif // V8_DEOPTIMIZER_H_ 783 #endif // V8_DEOPTIMIZER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698