v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
deoptimizer.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_DEOPTIMIZER_H_
29 #define V8_DEOPTIMIZER_H_
30 
31 #include "v8.h"
32 
33 #include "allocation.h"
34 #include "macro-assembler.h"
35 #include "zone-inl.h"
36 
37 
38 namespace v8 {
39 namespace internal {
40 
41 class FrameDescription;
42 class TranslationIterator;
43 class DeoptimizingCodeListNode;
44 class DeoptimizedFrameInfo;
45 
46 class HeapNumberMaterializationDescriptor BASE_EMBEDDED {
47  public:
48  HeapNumberMaterializationDescriptor(Address slot_address, double val)
49  : slot_address_(slot_address), val_(val) { }
50 
51  Address slot_address() const { return slot_address_; }
52  double value() const { return val_; }
53 
54  private:
55  Address slot_address_;
56  double val_;
57 };
58 
59 
60 class ArgumentsObjectMaterializationDescriptor BASE_EMBEDDED {
61  public:
63  : slot_address_(slot_address), arguments_length_(argc) { }
64 
65  Address slot_address() const { return slot_address_; }
66  int arguments_length() const { return arguments_length_; }
67 
68  private:
69  Address slot_address_;
70  int arguments_length_;
71 };
72 
73 
74 class OptimizedFunctionVisitor BASE_EMBEDDED {
75  public:
77 
78  // Function which is called before iteration of any optimized functions
79  // from given native context.
80  virtual void EnterContext(Context* context) = 0;
81 
82  virtual void VisitFunction(JSFunction* function) = 0;
83 
84  // Function which is called after iteration of all optimized functions
85  // from given native context.
86  virtual void LeaveContext(Context* context) = 0;
87 };
88 
89 
90 class Deoptimizer;
91 
92 
94  public:
97 
98 #ifdef ENABLE_DEBUGGER_SUPPORT
99  void Iterate(ObjectVisitor* v);
100 #endif
101 
102  private:
103  MemoryChunk* eager_deoptimization_entry_code_;
104  MemoryChunk* lazy_deoptimization_entry_code_;
105  Deoptimizer* current_;
106 
107 #ifdef ENABLE_DEBUGGER_SUPPORT
108  DeoptimizedFrameInfo* deoptimized_frame_info_;
109 #endif
110 
111  // List of deoptimized code which still have references from active stack
112  // frames. These code objects are needed by the deoptimizer when deoptimizing
113  // a frame for which the code object for the function function has been
114  // changed from the code present when deoptimizing was done.
115  DeoptimizingCodeListNode* deoptimizing_code_list_;
116 
117  friend class Deoptimizer;
118 
120 };
121 
122 
123 class Deoptimizer : public Malloced {
124  public:
125  enum BailoutType {
129  // This last bailout type is not really a bailout, but used by the
130  // debugger to deoptimize stack frames to allow inspection.
132  };
133 
134  int output_count() const { return output_count_; }
135 
136  // Number of created JS frames. Not all created frames are necessarily JS.
137  int jsframe_count() const { return jsframe_count_; }
138 
139  static Deoptimizer* New(JSFunction* function,
140  BailoutType type,
141  unsigned bailout_id,
142  Address from,
143  int fp_to_sp_delta,
144  Isolate* isolate);
145  static Deoptimizer* Grab(Isolate* isolate);
146 
147 #ifdef ENABLE_DEBUGGER_SUPPORT
148  // The returned object with information on the optimized frame needs to be
149  // freed before another one can be generated.
150  static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame,
151  int jsframe_index,
152  Isolate* isolate);
153  static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
154  Isolate* isolate);
155 #endif
156 
157  // Makes sure that there is enough room in the relocation
158  // information of a code object to perform lazy deoptimization
159  // patching. If there is not enough room a new relocation
160  // information object is allocated and comments are added until it
161  // is big enough.
163 
164  // Deoptimize the function now. Its current optimized code will never be run
165  // again and any activations of the optimized code will get deoptimized when
166  // execution returns.
167  static void DeoptimizeFunction(JSFunction* function);
168 
169  // Iterate over all the functions which share the same code object
170  // and make them use unoptimized version.
171  static void ReplaceCodeForRelatedFunctions(JSFunction* function, Code* code);
172 
173  // Deoptimize all functions in the heap.
174  static void DeoptimizeAll();
175 
176  static void DeoptimizeGlobalObject(JSObject* object);
177 
179  Context* context, OptimizedFunctionVisitor* visitor);
180 
182  JSObject* object, OptimizedFunctionVisitor* visitor);
183 
184  static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor* visitor);
185 
186  // The size in bytes of the code required at a lazy deopt patch site.
187  static int patch_size();
188 
189  // Patch all stack guard checks in the unoptimized code to
190  // unconditionally call replacement_code.
191  static void PatchStackCheckCode(Code* unoptimized_code,
192  Code* check_code,
193  Code* replacement_code);
194 
195  // Patch stack guard check at instruction before pc_after in
196  // the unoptimized code to unconditionally call replacement_code.
197  static void PatchStackCheckCodeAt(Code* unoptimized_code,
198  Address pc_after,
199  Code* check_code,
200  Code* replacement_code);
201 
202  // Change all patched stack guard checks in the unoptimized code
203  // back to a normal stack guard check.
204  static void RevertStackCheckCode(Code* unoptimized_code,
205  Code* check_code,
206  Code* replacement_code);
207 
208  // Change all patched stack guard checks in the unoptimized code
209  // back to a normal stack guard check.
210  static void RevertStackCheckCodeAt(Code* unoptimized_code,
211  Address pc_after,
212  Code* check_code,
213  Code* replacement_code);
214 
215  ~Deoptimizer();
216 
218 #ifdef ENABLE_DEBUGGER_SUPPORT
219  void MaterializeHeapNumbersForDebuggerInspectableFrame(
220  Address parameters_top,
221  uint32_t parameters_size,
222  Address expressions_top,
223  uint32_t expressions_size,
224  DeoptimizedFrameInfo* info);
225 #endif
226 
227  static void ComputeOutputFrames(Deoptimizer* deoptimizer);
228 
229  static Address GetDeoptimizationEntry(int id, BailoutType type);
230  static int GetDeoptimizationId(Address addr, BailoutType type);
231  static int GetOutputInfo(DeoptimizationOutputData* data,
232  BailoutId node_id,
233  SharedFunctionInfo* shared);
234 
235  // Code generation support.
236  static int input_offset() { return OFFSET_OF(Deoptimizer, input_); }
237  static int output_count_offset() {
238  return OFFSET_OF(Deoptimizer, output_count_);
239  }
240  static int output_offset() { return OFFSET_OF(Deoptimizer, output_); }
241 
243  return OFFSET_OF(Deoptimizer, has_alignment_padding_);
244  }
245 
246  static int GetDeoptimizedCodeCount(Isolate* isolate);
247 
248  static const int kNotDeoptimizationEntry = -1;
249 
250  // Generators for the deoptimization entry code.
251  class EntryGenerator BASE_EMBEDDED {
252  public:
254  : masm_(masm), type_(type) { }
255  virtual ~EntryGenerator() { }
256 
257  void Generate();
258 
259  protected:
260  MacroAssembler* masm() const { return masm_; }
261  BailoutType type() const { return type_; }
262 
263  virtual void GeneratePrologue() { }
264 
265  private:
266  MacroAssembler* masm_;
268  };
269 
270  class TableEntryGenerator : public EntryGenerator {
271  public:
273  : EntryGenerator(masm, type), count_(count) { }
274 
275  protected:
276  virtual void GeneratePrologue();
277 
278  private:
279  int count() const { return count_; }
280 
281  int count_;
282  };
283 
284  int ConvertJSFrameIndexToFrameIndex(int jsframe_index);
285 
286  private:
287  static const int kNumberOfEntries = 16384;
288 
289  Deoptimizer(Isolate* isolate,
290  JSFunction* function,
291  BailoutType type,
292  unsigned bailout_id,
293  Address from,
294  int fp_to_sp_delta,
295  Code* optimized_code);
296  void DeleteFrameDescriptions();
297 
298  void DoComputeOutputFrames();
299  void DoComputeOsrOutputFrame();
300  void DoComputeJSFrame(TranslationIterator* iterator, int frame_index);
301  void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
302  int frame_index);
303  void DoComputeConstructStubFrame(TranslationIterator* iterator,
304  int frame_index);
305  void DoComputeAccessorStubFrame(TranslationIterator* iterator,
306  int frame_index,
307  bool is_setter_stub_frame);
308  void DoTranslateCommand(TranslationIterator* iterator,
309  int frame_index,
310  unsigned output_offset);
311  // Translate a command for OSR. Updates the input offset to be used for
312  // the next command. Returns false if translation of the command failed
313  // (e.g., a number conversion failed) and may or may not have updated the
314  // input offset.
315  bool DoOsrTranslateCommand(TranslationIterator* iterator,
316  int* input_offset);
317 
318  unsigned ComputeInputFrameSize() const;
319  unsigned ComputeFixedSize(JSFunction* function) const;
320 
321  unsigned ComputeIncomingArgumentSize(JSFunction* function) const;
322  unsigned ComputeOutgoingArgumentSize() const;
323 
324  Object* ComputeLiteral(int index) const;
325 
326  void AddArgumentsObject(intptr_t slot_address, int argc);
327  void AddArgumentsObjectValue(intptr_t value);
328  void AddDoubleValue(intptr_t slot_address, double value);
329 
330  static MemoryChunk* CreateCode(BailoutType type);
331  static void GenerateDeoptimizationEntries(
332  MacroAssembler* masm, int count, BailoutType type);
333 
334  // Weak handle callback for deoptimizing code objects.
335  static void HandleWeakDeoptimizedCode(
336  v8::Persistent<v8::Value> obj, void* data);
337  static Code* FindDeoptimizingCodeFromAddress(Address addr);
338  static void RemoveDeoptimizingCode(Code* code);
339 
340  // Fill the input from from a JavaScript frame. This is used when
341  // the debugger needs to inspect an optimized frame. For normal
342  // deoptimizations the input frame is filled in generated code.
343  void FillInputFrame(Address tos, JavaScriptFrame* frame);
344 
345  Isolate* isolate_;
346  JSFunction* function_;
347  Code* optimized_code_;
348  unsigned bailout_id_;
349  BailoutType bailout_type_;
350  Address from_;
351  int fp_to_sp_delta_;
352  int has_alignment_padding_;
353 
354  // Input frame description.
355  FrameDescription* input_;
356  // Number of output frames.
357  int output_count_;
358  // Number of output js frames.
359  int jsframe_count_;
360  // Array of output frame descriptions.
361  FrameDescription** output_;
362 
363  List<Object*> deferred_arguments_objects_values_;
364  List<ArgumentsObjectMaterializationDescriptor> deferred_arguments_objects_;
365  List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_;
366 
367  static const int table_entry_size_;
368 
369  friend class FrameDescription;
371  friend class DeoptimizedFrameInfo;
372 };
373 
374 
376  public:
377  FrameDescription(uint32_t frame_size,
378  JSFunction* function);
379 
380  void* operator new(size_t size, uint32_t frame_size) {
381  // Subtracts kPointerSize, as the member frame_content_ already supplies
382  // the first element of the area to store the frame.
383  return malloc(size + frame_size - kPointerSize);
384  }
385 
386  void operator delete(void* pointer, uint32_t frame_size) {
387  free(pointer);
388  }
389 
390  void operator delete(void* description) {
391  free(description);
392  }
393 
394  uint32_t GetFrameSize() const {
395  ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_);
396  return static_cast<uint32_t>(frame_size_);
397  }
398 
399  JSFunction* GetFunction() const { return function_; }
400 
401  unsigned GetOffsetFromSlotIndex(int slot_index);
402 
403  intptr_t GetFrameSlot(unsigned offset) {
404  return *GetFrameSlotPointer(offset);
405  }
406 
407  double GetDoubleFrameSlot(unsigned offset) {
408  intptr_t* ptr = GetFrameSlotPointer(offset);
409 #if V8_TARGET_ARCH_MIPS
410  // Prevent gcc from using load-double (mips ldc1) on (possibly)
411  // non-64-bit aligned double. Uses two lwc1 instructions.
412  union conversion {
413  double d;
414  uint32_t u[2];
415  } c;
416  c.u[0] = *reinterpret_cast<uint32_t*>(ptr);
417  c.u[1] = *(reinterpret_cast<uint32_t*>(ptr) + 1);
418  return c.d;
419 #else
420  return *reinterpret_cast<double*>(ptr);
421 #endif
422  }
423 
424  void SetFrameSlot(unsigned offset, intptr_t value) {
425  *GetFrameSlotPointer(offset) = value;
426  }
427 
428  intptr_t GetRegister(unsigned n) const {
429  ASSERT(n < ARRAY_SIZE(registers_));
430  return registers_[n];
431  }
432 
433  double GetDoubleRegister(unsigned n) const {
434  ASSERT(n < ARRAY_SIZE(double_registers_));
435  return double_registers_[n];
436  }
437 
438  void SetRegister(unsigned n, intptr_t value) {
439  ASSERT(n < ARRAY_SIZE(registers_));
440  registers_[n] = value;
441  }
442 
443  void SetDoubleRegister(unsigned n, double value) {
444  ASSERT(n < ARRAY_SIZE(double_registers_));
445  double_registers_[n] = value;
446  }
447 
448  intptr_t GetTop() const { return top_; }
449  void SetTop(intptr_t top) { top_ = top; }
450 
451  intptr_t GetPc() const { return pc_; }
452  void SetPc(intptr_t pc) { pc_ = pc; }
453 
454  intptr_t GetFp() const { return fp_; }
455  void SetFp(intptr_t fp) { fp_ = fp; }
456 
457  intptr_t GetContext() const { return context_; }
458  void SetContext(intptr_t context) { context_ = context; }
459 
460  Smi* GetState() const { return state_; }
461  void SetState(Smi* state) { state_ = state; }
462 
463  void SetContinuation(intptr_t pc) { continuation_ = pc; }
464 
465  StackFrame::Type GetFrameType() const { return type_; }
466  void SetFrameType(StackFrame::Type type) { type_ = type; }
467 
468  // Get the incoming arguments count.
470 
471  // Get a parameter value for an unoptimized frame.
472  Object* GetParameter(int index);
473 
474  // Get the expression stack height for a unoptimized frame.
475  unsigned GetExpressionCount();
476 
477  // Get the expression stack value for an unoptimized frame.
478  Object* GetExpression(int index);
479 
480  static int registers_offset() {
481  return OFFSET_OF(FrameDescription, registers_);
482  }
483 
484  static int double_registers_offset() {
485  return OFFSET_OF(FrameDescription, double_registers_);
486  }
487 
488  static int frame_size_offset() {
489  return OFFSET_OF(FrameDescription, frame_size_);
490  }
491 
492  static int pc_offset() {
493  return OFFSET_OF(FrameDescription, pc_);
494  }
495 
496  static int state_offset() {
497  return OFFSET_OF(FrameDescription, state_);
498  }
499 
500  static int continuation_offset() {
501  return OFFSET_OF(FrameDescription, continuation_);
502  }
503 
504  static int frame_content_offset() {
505  return OFFSET_OF(FrameDescription, frame_content_);
506  }
507 
508  private:
509  static const uint32_t kZapUint32 = 0xbeeddead;
510 
511  // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to
512  // keep the variable-size array frame_content_ of type intptr_t at
513  // the end of the structure aligned.
514  uintptr_t frame_size_; // Number of bytes.
515  JSFunction* function_;
516  intptr_t registers_[Register::kNumRegisters];
517  double double_registers_[DoubleRegister::kNumAllocatableRegisters];
518  intptr_t top_;
519  intptr_t pc_;
520  intptr_t fp_;
521  intptr_t context_;
522  StackFrame::Type type_;
523  Smi* state_;
524 #ifdef DEBUG
525  Code::Kind kind_;
526 #endif
527 
528  // Continuation is the PC where the execution continues after
529  // deoptimizing.
530  intptr_t continuation_;
531 
532  // This must be at the end of the object as the object is allocated larger
533  // than it's definition indicate to extend this array.
534  intptr_t frame_content_[1];
535 
536  intptr_t* GetFrameSlotPointer(unsigned offset) {
537  ASSERT(offset < frame_size_);
538  return reinterpret_cast<intptr_t*>(
539  reinterpret_cast<Address>(this) + frame_content_offset() + offset);
540  }
541 
542  int ComputeFixedSize();
543 };
544 
545 
546 class TranslationBuffer BASE_EMBEDDED {
547  public:
548  explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { }
549 
550  int CurrentIndex() const { return contents_.length(); }
551  void Add(int32_t value, Zone* zone);
552 
553  Handle<ByteArray> CreateByteArray();
554 
555  private:
556  ZoneList<uint8_t> contents_;
557 };
558 
559 
560 class TranslationIterator BASE_EMBEDDED {
561  public:
562  TranslationIterator(ByteArray* buffer, int index)
563  : buffer_(buffer), index_(index) {
564  ASSERT(index >= 0 && index < buffer->length());
565  }
566 
567  int32_t Next();
568 
569  bool HasNext() const { return index_ < buffer_->length(); }
570 
571  void Skip(int n) {
572  for (int i = 0; i < n; i++) Next();
573  }
574 
575  private:
577  int index_;
578 };
579 
580 
581 class Translation BASE_EMBEDDED {
582  public:
583  enum Opcode {
600 
601  // A prefix indicating that the next command is a duplicate of the one
602  // that follows it.
603  DUPLICATE
604  };
605 
606  Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count,
607  Zone* zone)
608  : buffer_(buffer),
609  index_(buffer->CurrentIndex()),
610  zone_(zone) {
611  buffer_->Add(BEGIN, zone);
612  buffer_->Add(frame_count, zone);
613  buffer_->Add(jsframe_count, zone);
614  }
615 
616  int index() const { return index_; }
617 
618  // Commands.
619  void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height);
620  void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
621  void BeginConstructStubFrame(int literal_id, unsigned height);
622  void BeginGetterStubFrame(int literal_id);
623  void BeginSetterStubFrame(int literal_id);
624  void StoreRegister(Register reg);
625  void StoreInt32Register(Register reg);
626  void StoreUint32Register(Register reg);
627  void StoreDoubleRegister(DoubleRegister reg);
628  void StoreStackSlot(int index);
629  void StoreInt32StackSlot(int index);
630  void StoreUint32StackSlot(int index);
631  void StoreDoubleStackSlot(int index);
632  void StoreLiteral(int literal_id);
633  void StoreArgumentsObject(int args_index, int args_length);
634  void MarkDuplicate();
635 
636  Zone* zone() const { return zone_; }
637 
638  static int NumberOfOperandsFor(Opcode opcode);
639 
640 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
641  static const char* StringFor(Opcode opcode);
642 #endif
643 
644  // A literal id which refers to the JSFunction itself.
645  static const int kSelfLiteralId = -239;
646 
647  private:
648  TranslationBuffer* buffer_;
649  int index_;
650  Zone* zone_;
651 };
652 
653 
654 // Linked list holding deoptimizing code objects. The deoptimizing code objects
655 // are kept as weak handles until they are no longer activated on the stack.
657  public:
660 
661  DeoptimizingCodeListNode* next() const { return next_; }
663  Handle<Code> code() const { return code_; }
664 
665  private:
666  // Global (weak) handle to the deoptimizing code object.
667  Handle<Code> code_;
668 
669  // Next pointer for linked list.
671 };
672 
673 
674 class SlotRef BASE_EMBEDDED {
675  public:
682  LITERAL
683  };
684 
686  : addr_(NULL), representation_(UNKNOWN) { }
687 
688  SlotRef(Address addr, SlotRepresentation representation)
689  : addr_(addr), representation_(representation) { }
690 
691  explicit SlotRef(Object* literal)
692  : literal_(literal), representation_(LITERAL) { }
693 
695  switch (representation_) {
696  case TAGGED:
697  return Handle<Object>(Memory::Object_at(addr_));
698 
699  case INT32: {
700  int value = Memory::int32_at(addr_);
701  if (Smi::IsValid(value)) {
702  return Handle<Object>(Smi::FromInt(value));
703  } else {
704  return Isolate::Current()->factory()->NewNumberFromInt(value);
705  }
706  }
707 
708  case UINT32: {
709  uint32_t value = Memory::uint32_at(addr_);
710  if (value <= static_cast<uint32_t>(Smi::kMaxValue)) {
711  return Handle<Object>(Smi::FromInt(static_cast<int>(value)));
712  } else {
713  return Isolate::Current()->factory()->NewNumber(
714  static_cast<double>(value));
715  }
716  }
717 
718  case DOUBLE: {
719  double value = Memory::double_at(addr_);
720  return Isolate::Current()->factory()->NewNumber(value);
721  }
722 
723  case LITERAL:
724  return literal_;
725 
726  default:
727  UNREACHABLE();
728  return Handle<Object>::null();
729  }
730  }
731 
732  static Vector<SlotRef> ComputeSlotMappingForArguments(
733  JavaScriptFrame* frame,
734  int inlined_frame_index,
736 
737  private:
738  Address addr_;
739  Handle<Object> literal_;
740  SlotRepresentation representation_;
741 
742  static Address SlotAddress(JavaScriptFrame* frame, int slot_index) {
743  if (slot_index >= 0) {
744  const int offset = JavaScriptFrameConstants::kLocal0Offset;
745  return frame->fp() + offset - (slot_index * kPointerSize);
746  } else {
748  return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
749  }
750  }
751 
752  static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator,
753  DeoptimizationInputData* data,
754  JavaScriptFrame* frame);
755 
756  static void ComputeSlotsForArguments(
757  Vector<SlotRef>* args_slots,
758  TranslationIterator* iterator,
759  DeoptimizationInputData* data,
760  JavaScriptFrame* frame);
761 };
762 
763 
764 #ifdef ENABLE_DEBUGGER_SUPPORT
765 // Class used to represent an unoptimized frame when the debugger
766 // needs to inspect a frame that is part of an optimized frame. The
767 // internally used FrameDescription objects are not GC safe so for use
768 // by the debugger frame information is copied to an object of this type.
769 // Represents parameters in unadapted form so their number might mismatch
770 // formal parameter count.
771 class DeoptimizedFrameInfo : public Malloced {
772  public:
773  DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
774  int frame_index,
775  bool has_arguments_adaptor,
776  bool has_construct_stub);
777  virtual ~DeoptimizedFrameInfo();
778 
779  // GC support.
780  void Iterate(ObjectVisitor* v);
781 
782  // Return the number of incoming arguments.
783  int parameters_count() { return parameters_count_; }
784 
785  // Return the height of the expression stack.
786  int expression_count() { return expression_count_; }
787 
788  // Get the frame function.
789  JSFunction* GetFunction() {
790  return function_;
791  }
792 
793  // Check if this frame is preceded by construct stub frame. The bottom-most
794  // inlined frame might still be called by an uninlined construct stub.
795  bool HasConstructStub() {
796  return has_construct_stub_;
797  }
798 
799  // Get an incoming argument.
800  Object* GetParameter(int index) {
801  ASSERT(0 <= index && index < parameters_count());
802  return parameters_[index];
803  }
804 
805  // Get an expression from the expression stack.
806  Object* GetExpression(int index) {
807  ASSERT(0 <= index && index < expression_count());
808  return expression_stack_[index];
809  }
810 
811  int GetSourcePosition() {
812  return source_position_;
813  }
814 
815  private:
816  // Set an incoming argument.
817  void SetParameter(int index, Object* obj) {
818  ASSERT(0 <= index && index < parameters_count());
819  parameters_[index] = obj;
820  }
821 
822  // Set an expression on the expression stack.
823  void SetExpression(int index, Object* obj) {
824  ASSERT(0 <= index && index < expression_count());
825  expression_stack_[index] = obj;
826  }
827 
828  JSFunction* function_;
829  bool has_construct_stub_;
830  int parameters_count_;
831  int expression_count_;
832  Object** parameters_;
833  Object** expression_stack_;
834  int source_position_;
835 
836  friend class Deoptimizer;
837 };
838 #endif
839 
840 } } // namespace v8::internal
841 
842 #endif // V8_DEOPTIMIZER_H_
byte * Address
Definition: globals.h:157
DeoptimizingCodeListNode * next() const
Definition: deoptimizer.h:661
static Object *& Object_at(Address addr)
Definition: v8memory.h:75
HeapNumberMaterializationDescriptor(Address slot_address, double val)
Definition: deoptimizer.h:48
static Smi * FromInt(int value)
Definition: objects-inl.h:981
unsigned GetOffsetFromSlotIndex(int slot_index)
static double & double_at(Address addr)
Definition: v8memory.h:67
void SetFrameSlot(unsigned offset, intptr_t value)
Definition: deoptimizer.h:424
static void RevertStackCheckCode(Code *unoptimized_code, Code *check_code, Code *replacement_code)
static void ComputeOutputFrames(Deoptimizer *deoptimizer)
Definition: deoptimizer.cc:349
Address slot_address() const
Definition: deoptimizer.h:51
SlotRef(Object *literal)
Definition: deoptimizer.h:691
int int32_t
Definition: unicode.cc:47
Definition: deoptimizer.h:270
static const int kNumAllocatableRegisters
SlotRef(Address addr, SlotRepresentation representation)
Definition: deoptimizer.h:688
#define ASSERT(condition)
Definition: checks.h:270
static void DeoptimizeFunction(JSFunction *function)
static void DeoptimizeAll()
Definition: deoptimizer.cc:250
Handle< Object > GetValue()
Definition: deoptimizer.h:694
double GetDoubleRegister(unsigned n) const
Definition: deoptimizer.h:433
intptr_t GetContext() const
Definition: deoptimizer.h:457
int arguments_length() const
Definition: deoptimizer.h:66
void MaterializeHeapObjects(JavaScriptFrameIterator *it)
Definition: deoptimizer.cc:639
void SetFrameType(StackFrame::Type type)
Definition: deoptimizer.h:466
StringInputBuffer *const buffer_
static const int kNumRegisters
Definition: assembler-arm.h:73
static int double_registers_offset()
Definition: deoptimizer.h:484
MacroAssembler * masm() const
Definition: deoptimizer.h:260
JSFunction * GetFunction() const
Definition: deoptimizer.h:399
static void DeoptimizeGlobalObject(JSObject *object)
Definition: deoptimizer.cc:262
#define UNREACHABLE()
Definition: checks.h:50
static int output_offset()
Definition: deoptimizer.h:240
TableEntryGenerator(MacroAssembler *masm, BailoutType type, int count)
Definition: deoptimizer.h:272
#define OFFSET_OF(type, field)
Definition: globals.h:273
static bool IsValid(intptr_t value)
Definition: objects-inl.h:1059
const int kPointerSize
Definition: globals.h:220
Translation(TranslationBuffer *buffer, int frame_count, int jsframe_count, Zone *zone)
Definition: deoptimizer.h:606
static int32_t & int32_at(Address addr)
Definition: v8memory.h:51
EntryGenerator(MacroAssembler *masm, BailoutType type)
Definition: deoptimizer.h:253
void SetRegister(unsigned n, intptr_t value)
Definition: deoptimizer.h:438
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:307
const Register pc
static int GetDeoptimizedCodeCount(Isolate *isolate)
Definition: deoptimizer.cc:523
void set_next(DeoptimizingCodeListNode *next)
Definition: deoptimizer.h:662
static void EnsureRelocSpaceForLazyDeoptimization(Handle< Code > code)
static int GetOutputInfo(DeoptimizationOutputData *data, BailoutId node_id, SharedFunctionInfo *shared)
Definition: deoptimizer.cc:498
static void ReplaceCodeForRelatedFunctions(JSFunction *function, Code *code)
static void PatchStackCheckCode(Code *unoptimized_code, Code *check_code, Code *replacement_code)
#define BASE_EMBEDDED
Definition: allocation.h:68
uint32_t GetFrameSize() const
Definition: deoptimizer.h:394
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kInstanceClassNameOffset kHiddenPrototypeBit kReadOnlyPrototypeBit kIsTopLevelBit kAllowLazyCompilation kUsesArguments formal_parameter_count
Definition: objects-inl.h:4003
static void VisitAllOptimizedFunctionsForContext(Context *context, OptimizedFunctionVisitor *visitor)
Definition: deoptimizer.cc:270
void SetContinuation(intptr_t pc)
Definition: deoptimizer.h:463
virtual ~OptimizedFunctionVisitor()
Definition: deoptimizer.h:76
static int output_count_offset()
Definition: deoptimizer.h:237
static void RevertStackCheckCodeAt(Code *unoptimized_code, Address pc_after, Code *check_code, Code *replacement_code)
intptr_t GetFrameSlot(unsigned offset)
Definition: deoptimizer.h:403
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
Definition: frames.h:775
friend class DeoptimizedFrameInfo
Definition: deoptimizer.h:371
static Address GetDeoptimizationEntry(int id, BailoutType type)
Definition: deoptimizer.cc:457
TranslationIterator(ByteArray *buffer, int index)
Definition: deoptimizer.h:562
static Deoptimizer * Grab(Isolate *isolate)
Definition: deoptimizer.cc:99
static const int kNotDeoptimizationEntry
Definition: deoptimizer.h:248
static Handle< T > null()
Definition: handles.h:86
friend class FrameDescription
Definition: deoptimizer.h:369
StackFrame::Type GetFrameType() const
Definition: deoptimizer.h:465
virtual void GeneratePrologue()
double GetDoubleFrameSlot(unsigned offset)
Definition: deoptimizer.h:407
FrameDescription(uint32_t frame_size, JSFunction *function)
static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor *visitor)
Definition: deoptimizer.cc:315
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
void SetContext(intptr_t context)
Definition: deoptimizer.h:458
static uint32_t & uint32_at(Address addr)
Definition: v8memory.h:47
int ConvertJSFrameIndexToFrameIndex(int jsframe_index)
Definition: deoptimizer.cc:109
static void VisitAllOptimizedFunctionsForGlobalObject(JSObject *object, OptimizedFunctionVisitor *visitor)
Definition: deoptimizer.cc:299
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
const Register fp
intptr_t GetRegister(unsigned n) const
Definition: deoptimizer.h:428
void SetDoubleRegister(unsigned n, double value)
Definition: deoptimizer.h:443
int jsframe_count() const
Definition: deoptimizer.h:137
static const int kMaxValue
Definition: objects.h:1050
static int GetDeoptimizationId(Address addr, BailoutType type)
Definition: deoptimizer.cc:478
#define ARRAY_SIZE(a)
Definition: globals.h:281
ArgumentsObjectMaterializationDescriptor(Address slot_address, int argc)
Definition: deoptimizer.h:62
static void PatchStackCheckCodeAt(Code *unoptimized_code, Address pc_after, Code *check_code, Code *replacement_code)
void SetTop(intptr_t top)
Definition: deoptimizer.h:449
static int has_alignment_padding_offset()
Definition: deoptimizer.h:242
static Deoptimizer * New(JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Isolate *isolate)
Definition: deoptimizer.cc:79
Object * GetExpression(int index)
Object * GetParameter(int index)