V8 Project
deoptimizer.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_DEOPTIMIZER_H_
6 #define V8_DEOPTIMIZER_H_
7 
8 #include "src/v8.h"
9 
10 #include "src/allocation.h"
11 #include "src/macro-assembler.h"
12 #include "src/zone-inl.h"
13 
14 
15 namespace v8 {
16 namespace internal {
17 
18 
19 static inline double read_double_value(Address p) {
20  double d;
21  memcpy(&d, p, sizeof(d));
22  return d;
23 }
24 
25 
26 class FrameDescription;
27 class TranslationIterator;
28 class DeoptimizedFrameInfo;
29 
30 template<typename T>
31 class HeapNumberMaterializationDescriptor BASE_EMBEDDED {
32  public:
33  HeapNumberMaterializationDescriptor(T destination, double value)
34  : destination_(destination), value_(value) { }
35 
36  T destination() const { return destination_; }
37  double value() const { return value_; }
38 
39  private:
41  double value_;
42 };
43 
44 
45 class ObjectMaterializationDescriptor BASE_EMBEDDED {
46  public:
48  Address slot_address, int frame, int length, int duplicate, bool is_args)
49  : slot_address_(slot_address),
50  jsframe_index_(frame),
51  object_length_(length),
52  duplicate_object_(duplicate),
53  is_arguments_(is_args) { }
54 
55  Address slot_address() const { return slot_address_; }
56  int jsframe_index() const { return jsframe_index_; }
57  int object_length() const { return object_length_; }
58  int duplicate_object() const { return duplicate_object_; }
59  bool is_arguments() const { return is_arguments_; }
60 
61  // Only used for allocated receivers in DoComputeConstructStubFrame.
62  void patch_slot_address(intptr_t slot) {
63  slot_address_ = reinterpret_cast<Address>(slot);
64  }
65 
66  private:
72 };
73 
74 
76  public:
78 
79  // Function which is called before iteration of any optimized functions
80  // from given native context.
81  virtual void EnterContext(Context* context) = 0;
82 
83  virtual void VisitFunction(JSFunction* function) = 0;
84 
85  // Function which is called after iteration of all optimized functions
86  // from given native context.
87  virtual void LeaveContext(Context* context) = 0;
88 };
89 
90 
91 class Deoptimizer : public Malloced {
92  public:
93  enum BailoutType {
97  // This last bailout type is not really a bailout, but used by the
98  // debugger to deoptimize stack frames to allow inspection.
99  DEBUGGER
100  };
101 
102  static const int kBailoutTypesWithCodeEntry = SOFT + 1;
103 
104  struct Reason {
105  Reason(int r, const char* m, const char* d)
106  : raw_position(r), mnemonic(m), detail(d) {}
107 
108  bool operator==(const Reason& other) const {
109  return raw_position == other.raw_position &&
110  CStringEquals(mnemonic, other.mnemonic) &&
111  CStringEquals(detail, other.detail);
112  }
113 
114  bool operator!=(const Reason& other) const { return !(*this == other); }
115 
117  const char* mnemonic;
118  const char* detail;
119  };
120 
121  struct JumpTableEntry : public ZoneObject {
122  inline JumpTableEntry(Address entry, const Reason& the_reason,
123  Deoptimizer::BailoutType type, bool frame)
124  : label(),
125  address(entry),
126  reason(the_reason),
127  bailout_type(type),
128  needs_frame(frame) {}
129 
130  bool IsEquivalentTo(const JumpTableEntry& other) const {
131  return address == other.address && bailout_type == other.bailout_type &&
132  needs_frame == other.needs_frame &&
133  (!FLAG_trace_deopt || reason == other.reason);
134  }
135 
136  Label label;
141  };
142 
143  static bool TraceEnabledFor(BailoutType deopt_type,
144  StackFrame::Type frame_type);
145  static const char* MessageFor(BailoutType type);
146 
147  int output_count() const { return output_count_; }
148 
149  Handle<JSFunction> function() const { return Handle<JSFunction>(function_); }
152 
153  // Number of created JS frames. Not all created frames are necessarily JS.
154  int jsframe_count() const { return jsframe_count_; }
155 
156  static Deoptimizer* New(JSFunction* function,
157  BailoutType type,
158  unsigned bailout_id,
159  Address from,
160  int fp_to_sp_delta,
161  Isolate* isolate);
162  static Deoptimizer* Grab(Isolate* isolate);
163 
164  // The returned object with information on the optimized frame needs to be
165  // freed before another one can be generated.
167  int jsframe_index,
168  Isolate* isolate);
170  Isolate* isolate);
171 
172  // Makes sure that there is enough room in the relocation
173  // information of a code object to perform lazy deoptimization
174  // patching. If there is not enough room a new relocation
175  // information object is allocated and comments are added until it
176  // is big enough.
178 
179  // Deoptimize the function now. Its current optimized code will never be run
180  // again and any activations of the optimized code will get deoptimized when
181  // execution returns.
182  static void DeoptimizeFunction(JSFunction* function);
183 
184  // Deoptimize all code in the given isolate.
185  static void DeoptimizeAll(Isolate* isolate);
186 
187  // Deoptimize code associated with the given global object.
188  static void DeoptimizeGlobalObject(JSObject* object);
189 
190  // Deoptimizes all optimized code that has been previously marked
191  // (via code->set_marked_for_deoptimization) and unlinks all functions that
192  // refer to that code.
193  static void DeoptimizeMarkedCode(Isolate* isolate);
194 
195  // Visit all the known optimized functions in a given isolate.
196  static void VisitAllOptimizedFunctions(
198 
199  // The size in bytes of the code required at a lazy deopt patch site.
200  static int patch_size();
201 
202  ~Deoptimizer();
203 
204  void MaterializeHeapObjects(JavaScriptFrameIterator* it);
205 
207  Address parameters_top,
208  uint32_t parameters_size,
209  Address expressions_top,
210  uint32_t expressions_size,
211  DeoptimizedFrameInfo* info);
212 
213  static void ComputeOutputFrames(Deoptimizer* deoptimizer);
214 
215 
219  };
220 
221 
223  Isolate* isolate,
224  int id,
225  BailoutType type,
227  static int GetDeoptimizationId(Isolate* isolate,
228  Address addr,
229  BailoutType type);
230  static int GetOutputInfo(DeoptimizationOutputData* data,
231  BailoutId node_id,
232  SharedFunctionInfo* shared);
233 
234  // Code generation support.
235  static int input_offset() { return OFFSET_OF(Deoptimizer, input_); }
236  static int output_count_offset() {
238  }
239  static int output_offset() { return OFFSET_OF(Deoptimizer, output_); }
240 
243  }
244 
246 
247  static const int kNotDeoptimizationEntry = -1;
248 
249  // Generators for the deoptimization entry code.
251  public:
253  : masm_(masm), type_(type) { }
254  virtual ~EntryGenerator() { }
255 
256  void Generate();
257 
258  protected:
259  MacroAssembler* masm() const { return masm_; }
260  BailoutType type() const { return type_; }
261  Isolate* isolate() const { return masm_->isolate(); }
262 
263  virtual void GeneratePrologue() { }
264 
265  private:
268  };
269 
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  static size_t GetMaxDeoptTableSize();
287 
289  BailoutType type,
290  int max_entry_id);
291 
292  Isolate* isolate() const { return isolate_; }
293 
294  private:
295  static const int kMinNumberOfEntries = 64;
296  static const int kMaxNumberOfEntries = 16384;
297 
299  JSFunction* function,
300  BailoutType type,
301  unsigned bailout_id,
302  Address from,
303  int fp_to_sp_delta,
304  Code* optimized_code);
305  Code* FindOptimizedCode(JSFunction* function, Code* optimized_code);
306  void PrintFunctionName();
308 
309  void DoComputeOutputFrames();
310  void DoComputeJSFrame(TranslationIterator* iterator, int frame_index);
311  void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
312  int frame_index);
313  void DoComputeConstructStubFrame(TranslationIterator* iterator,
314  int frame_index);
315  void DoComputeAccessorStubFrame(TranslationIterator* iterator,
316  int frame_index,
317  bool is_setter_stub_frame);
318  void DoComputeCompiledStubFrame(TranslationIterator* iterator,
319  int frame_index);
320 
321  // Translate object, store the result into an auxiliary array
322  // (deferred_objects_tagged_values_).
323  void DoTranslateObject(TranslationIterator* iterator,
324  int object_index,
325  int field_index);
326 
327  // Translate value, store the result into the given frame slot.
328  void DoTranslateCommand(TranslationIterator* iterator,
329  int frame_index,
330  unsigned output_offset);
331 
332  // Translate object, do not store the result anywhere (but do update
333  // the deferred materialization array).
334  void DoTranslateObjectAndSkip(TranslationIterator* iterator);
335 
336  unsigned ComputeInputFrameSize() const;
337  unsigned ComputeFixedSize(JSFunction* function) const;
338 
339  unsigned ComputeIncomingArgumentSize(JSFunction* function) const;
340  unsigned ComputeOutgoingArgumentSize() const;
341 
342  Object* ComputeLiteral(int index) const;
343 
344  void AddObjectStart(intptr_t slot_address, int argc, bool is_arguments);
345  void AddObjectDuplication(intptr_t slot, int object_index);
346  void AddObjectTaggedValue(intptr_t value);
347  void AddObjectDoubleValue(double value);
348  void AddDoubleValue(intptr_t slot_address, double value);
349 
350  bool ArgumentsObjectIsAdapted(int object_index) {
351  ObjectMaterializationDescriptor desc = deferred_objects_.at(object_index);
352  int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
353  return jsframe_has_adapted_arguments_[reverse_jsframe_index];
354  }
355 
357  ObjectMaterializationDescriptor desc = deferred_objects_.at(object_index);
358  int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
359  return jsframe_functions_[reverse_jsframe_index];
360  }
361 
362  // Helper function for heap object materialization.
365 
366  static void GenerateDeoptimizationEntries(
367  MacroAssembler* masm, int count, BailoutType type);
368 
369  // Marks all the code in the given context for deoptimization.
370  static void MarkAllCodeForContext(Context* native_context);
371 
372  // Visit all the known optimized functions in a given context.
374  Context* context, OptimizedFunctionVisitor* visitor);
375 
376  // Deoptimizes all code marked in the given context.
377  static void DeoptimizeMarkedCodeForContext(Context* native_context);
378 
379  // Patch the given code so that it will deoptimize itself.
380  static void PatchCodeForDeoptimization(Isolate* isolate, Code* code);
381 
382  // Searches the list of known deoptimizing code for a Code object
383  // containing the given address (which is supposedly faster than
384  // searching all code objects).
386 
387  // Fill the input from from a JavaScript frame. This is used when
388  // the debugger needs to inspect an optimized frame. For normal
389  // deoptimizations the input frame is filled in generated code.
390  void FillInputFrame(Address tos, JavaScriptFrame* frame);
391 
392  // Fill the given output frame's registers to contain the failure handler
393  // address and the number of parameters for a stub failure trampoline.
395  CodeStubDescriptor* desc);
396 
397  // Fill the given output frame's double registers with the original values
398  // from the input frame's double registers.
399  void CopyDoubleRegisters(FrameDescription* output_frame);
400 
401  // Determines whether the input frame contains alignment padding by looking
402  // at the dynamic alignment state slot inside the frame.
403  bool HasAlignmentPadding(JSFunction* function);
404 
408  unsigned bailout_id_;
413 
414  // Input frame description.
416  // Number of output frames.
418  // Number of output js frames.
420  // Array of output frame descriptions.
422 
423  // Deferred values to be materialized.
429 
430  // Key for lookup of previously materialized objects
434 
435  // Output frame information. Only used during heap object materialization.
438 
439  // Materialized objects. Only used during heap object materialization.
444 
445 #ifdef DEBUG
446  DisallowHeapAllocation* disallow_heap_allocation_;
447 #endif // DEBUG
448 
449  CodeTracer::Scope* trace_scope_;
450 
451  static const int table_entry_size_;
452 
453  friend class FrameDescription;
454  friend class DeoptimizedFrameInfo;
455 };
456 
457 
459  public:
460  FrameDescription(uint32_t frame_size,
461  JSFunction* function);
462 
463  void* operator new(size_t size, uint32_t frame_size) {
464  // Subtracts kPointerSize, as the member frame_content_ already supplies
465  // the first element of the area to store the frame.
466  return malloc(size + frame_size - kPointerSize);
467  }
468 
469  void operator delete(void* pointer, uint32_t frame_size) {
470  free(pointer);
471  }
472 
473  void operator delete(void* description) {
474  free(description);
475  }
476 
478  DCHECK(static_cast<uint32_t>(frame_size_) == frame_size_);
479  return static_cast<uint32_t>(frame_size_);
480  }
481 
482  JSFunction* GetFunction() const { return function_; }
483 
484  unsigned GetOffsetFromSlotIndex(int slot_index);
485 
486  intptr_t GetFrameSlot(unsigned offset) {
487  return *GetFrameSlotPointer(offset);
488  }
489 
490  double GetDoubleFrameSlot(unsigned offset) {
491  intptr_t* ptr = GetFrameSlotPointer(offset);
492  return read_double_value(reinterpret_cast<Address>(ptr));
493  }
494 
495  void SetFrameSlot(unsigned offset, intptr_t value) {
496  *GetFrameSlotPointer(offset) = value;
497  }
498 
499  void SetCallerPc(unsigned offset, intptr_t value);
500 
501  void SetCallerFp(unsigned offset, intptr_t value);
502 
503  void SetCallerConstantPool(unsigned offset, intptr_t value);
504 
505  intptr_t GetRegister(unsigned n) const {
506 #if DEBUG
507  // This convoluted DCHECK is needed to work around a gcc problem that
508  // improperly detects an array bounds overflow in optimized debug builds
509  // when using a plain DCHECK.
510  if (n >= arraysize(registers_)) {
511  DCHECK(false);
512  return 0;
513  }
514 #endif
515  return registers_[n];
516  }
517 
518  double GetDoubleRegister(unsigned n) const {
520  return double_registers_[n];
521  }
522 
523  void SetRegister(unsigned n, intptr_t value) {
525  registers_[n] = value;
526  }
527 
528  void SetDoubleRegister(unsigned n, double value) {
530  double_registers_[n] = value;
531  }
532 
533  intptr_t GetTop() const { return top_; }
534  void SetTop(intptr_t top) { top_ = top; }
535 
536  intptr_t GetPc() const { return pc_; }
537  void SetPc(intptr_t pc) { pc_ = pc; }
538 
539  intptr_t GetFp() const { return fp_; }
540  void SetFp(intptr_t fp) { fp_ = fp; }
541 
542  intptr_t GetContext() const { return context_; }
543  void SetContext(intptr_t context) { context_ = context; }
544 
545  intptr_t GetConstantPool() const { return constant_pool_; }
546  void SetConstantPool(intptr_t constant_pool) {
547  constant_pool_ = constant_pool;
548  }
549 
550  Smi* GetState() const { return state_; }
551  void SetState(Smi* state) { state_ = state; }
552 
553  void SetContinuation(intptr_t pc) { continuation_ = pc; }
554 
555  StackFrame::Type GetFrameType() const { return type_; }
556  void SetFrameType(StackFrame::Type type) { type_ = type; }
557 
558  // Get the incoming arguments count.
560 
561  // Get a parameter value for an unoptimized frame.
562  Object* GetParameter(int index);
563 
564  // Get the expression stack height for a unoptimized frame.
565  unsigned GetExpressionCount();
566 
567  // Get the expression stack value for an unoptimized frame.
568  Object* GetExpression(int index);
569 
570  static int registers_offset() {
572  }
573 
574  static int double_registers_offset() {
576  }
577 
578  static int frame_size_offset() {
580  }
581 
582  static int pc_offset() {
583  return OFFSET_OF(FrameDescription, pc_);
584  }
585 
586  static int state_offset() {
588  }
589 
590  static int continuation_offset() {
592  }
593 
594  static int frame_content_offset() {
596  }
597 
598  private:
599  static const uint32_t kZapUint32 = 0xbeeddead;
600 
601  // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to
602  // keep the variable-size array frame_content_ of type intptr_t at
603  // the end of the structure aligned.
604  uintptr_t frame_size_; // Number of bytes.
608  intptr_t top_;
609  intptr_t pc_;
610  intptr_t fp_;
611  intptr_t context_;
612  intptr_t constant_pool_;
615 
616  // Continuation is the PC where the execution continues after
617  // deoptimizing.
618  intptr_t continuation_;
619 
620  // This must be at the end of the object as the object is allocated larger
621  // than it's definition indicate to extend this array.
622  intptr_t frame_content_[1];
623 
624  intptr_t* GetFrameSlotPointer(unsigned offset) {
625  DCHECK(offset < frame_size_);
626  return reinterpret_cast<intptr_t*>(
627  reinterpret_cast<Address>(this) + frame_content_offset() + offset);
628  }
629 
630  int ComputeFixedSize();
631 };
632 
633 
635  public:
636  explicit DeoptimizerData(MemoryAllocator* allocator);
638 
639  void Iterate(ObjectVisitor* v);
640 
641  private:
645 
647 
649 
650  friend class Deoptimizer;
651 
653 };
654 
655 
656 class TranslationBuffer BASE_EMBEDDED {
657  public:
658  explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { }
659 
660  int CurrentIndex() const { return contents_.length(); }
661  void Add(int32_t value, Zone* zone);
662 
664 
665  private:
667 };
668 
669 
670 class TranslationIterator BASE_EMBEDDED {
671  public:
672  TranslationIterator(ByteArray* buffer, int index)
673  : buffer_(buffer), index_(index) {
674  DCHECK(index >= 0 && index < buffer->length());
675  }
676 
678 
679  bool HasNext() const { return index_ < buffer_->length(); }
680 
681  void Skip(int n) {
682  for (int i = 0; i < n; i++) Next();
683  }
684 
685  private:
687  int index_;
688 };
689 
690 
691 #define TRANSLATION_OPCODE_LIST(V) \
692  V(BEGIN) \
693  V(JS_FRAME) \
694  V(CONSTRUCT_STUB_FRAME) \
695  V(GETTER_STUB_FRAME) \
696  V(SETTER_STUB_FRAME) \
697  V(ARGUMENTS_ADAPTOR_FRAME) \
698  V(COMPILED_STUB_FRAME) \
699  V(DUPLICATED_OBJECT) \
700  V(ARGUMENTS_OBJECT) \
701  V(CAPTURED_OBJECT) \
702  V(REGISTER) \
703  V(INT32_REGISTER) \
704  V(UINT32_REGISTER) \
705  V(DOUBLE_REGISTER) \
706  V(STACK_SLOT) \
707  V(INT32_STACK_SLOT) \
708  V(UINT32_STACK_SLOT) \
709  V(DOUBLE_STACK_SLOT) \
710  V(LITERAL)
711 
712 
713 class Translation BASE_EMBEDDED {
714  public:
715 #define DECLARE_TRANSLATION_OPCODE_ENUM(item) item,
716  enum Opcode {
718  LAST = LITERAL
719  };
720 #undef DECLARE_TRANSLATION_OPCODE_ENUM
721 
722  Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count,
723  Zone* zone)
724  : buffer_(buffer),
725  index_(buffer->CurrentIndex()),
726  zone_(zone) {
727  buffer_->Add(BEGIN, zone);
728  buffer_->Add(frame_count, zone);
729  buffer_->Add(jsframe_count, zone);
730  }
731 
732  int index() const { return index_; }
733 
734  // Commands.
735  void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height);
737  void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
738  void BeginConstructStubFrame(int literal_id, unsigned height);
739  void BeginGetterStubFrame(int literal_id);
740  void BeginSetterStubFrame(int literal_id);
741  void BeginArgumentsObject(int args_length);
742  void BeginCapturedObject(int length);
743  void DuplicateObject(int object_index);
748  void StoreStackSlot(int index);
749  void StoreInt32StackSlot(int index);
750  void StoreUint32StackSlot(int index);
751  void StoreDoubleStackSlot(int index);
752  void StoreLiteral(int literal_id);
753  void StoreArgumentsObject(bool args_known, int args_index, int args_length);
754 
755  Zone* zone() const { return zone_; }
756 
757  static int NumberOfOperandsFor(Opcode opcode);
758 
759 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
760  static const char* StringFor(Opcode opcode);
761 #endif
762 
763  // A literal id which refers to the JSFunction itself.
764  static const int kSelfLiteralId = -239;
765 
766  private:
767  TranslationBuffer* buffer_;
768  int index_;
769  Zone* zone_;
770 };
771 
772 
773 class SlotRef BASE_EMBEDDED {
774  public:
782  DEFERRED_OBJECT, // Object captured by the escape analysis.
783  // The number of nested objects can be obtained
784  // with the DeferredObjectLength() method
785  // (the SlotRefs of the nested objects follow
786  // this SlotRef in the depth-first order.)
787  DUPLICATE_OBJECT, // Duplicated object of a deferred object.
788  ARGUMENTS_OBJECT // Arguments object - only used to keep indexing
789  // in sync, it should not be materialized.
790  };
791 
793  : addr_(NULL), representation_(UNKNOWN) { }
794 
795  SlotRef(Address addr, SlotRepresentation representation)
796  : addr_(addr), representation_(representation) { }
797 
798  SlotRef(Isolate* isolate, Object* literal)
799  : literal_(literal, isolate), representation_(LITERAL) { }
800 
801  static SlotRef NewArgumentsObject(int length) {
802  SlotRef slot;
803  slot.representation_ = ARGUMENTS_OBJECT;
804  slot.deferred_object_length_ = length;
805  return slot;
806  }
807 
808  static SlotRef NewDeferredObject(int length) {
809  SlotRef slot;
810  slot.representation_ = DEFERRED_OBJECT;
811  slot.deferred_object_length_ = length;
812  return slot;
813  }
814 
815  SlotRepresentation Representation() { return representation_; }
816 
817  static SlotRef NewDuplicateObject(int id) {
818  SlotRef slot;
819  slot.representation_ = DUPLICATE_OBJECT;
820  slot.duplicate_object_id_ = id;
821  return slot;
822  }
823 
825  if (representation_ == DEFERRED_OBJECT ||
826  representation_ == ARGUMENTS_OBJECT) {
827  return deferred_object_length_;
828  } else {
829  return 0;
830  }
831  }
832 
833  int DuplicateObjectId() { return duplicate_object_id_; }
834 
836 
837  private:
843 };
844 
845 class SlotRefValueBuilder BASE_EMBEDDED {
846  public:
848  JavaScriptFrame* frame,
849  int inlined_frame_index,
850  int formal_parameter_count);
851 
852  void Prepare(Isolate* isolate);
853  Handle<Object> GetNext(Isolate* isolate, int level);
854  void Finish(Isolate* isolate);
855 
856  int args_length() { return args_length_; }
857 
858  private:
867 
869  Translation::Opcode opcode,
870  TranslationIterator* iterator,
872  JavaScriptFrame* frame);
873 
875 
876  static Address SlotAddress(JavaScriptFrame* frame, int slot_index) {
877  if (slot_index >= 0) {
878  const int offset = JavaScriptFrameConstants::kLocal0Offset;
879  return frame->fp() + offset - (slot_index * kPointerSize);
880  } else {
882  return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
883  }
884  }
885 
887 };
888 
890  public:
892  }
893 
895  void Set(Address fp, Handle<FixedArray> materialized_objects);
896  void Remove(Address fp);
897 
898  private:
899  Isolate* isolate() { return isolate_; }
902 
904 
907 };
908 
909 
910 // Class used to represent an unoptimized frame when the debugger
911 // needs to inspect a frame that is part of an optimized frame. The
912 // internally used FrameDescription objects are not GC safe so for use
913 // by the debugger frame information is copied to an object of this type.
914 // Represents parameters in unadapted form so their number might mismatch
915 // formal parameter count.
917  public:
918  DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
919  int frame_index,
920  bool has_arguments_adaptor,
921  bool has_construct_stub);
922  virtual ~DeoptimizedFrameInfo();
923 
924  // GC support.
925  void Iterate(ObjectVisitor* v);
926 
927  // Return the number of incoming arguments.
929 
930  // Return the height of the expression stack.
932 
933  // Get the frame function.
935  return function_;
936  }
937 
938  // Get the frame context.
939  Object* GetContext() { return context_; }
940 
941  // Check if this frame is preceded by construct stub frame. The bottom-most
942  // inlined frame might still be called by an uninlined construct stub.
944  return has_construct_stub_;
945  }
946 
947  // Get an incoming argument.
948  Object* GetParameter(int index) {
949  DCHECK(0 <= index && index < parameters_count());
950  return parameters_[index];
951  }
952 
953  // Get an expression from the expression stack.
954  Object* GetExpression(int index) {
955  DCHECK(0 <= index && index < expression_count());
956  return expression_stack_[index];
957  }
958 
960  return source_position_;
961  }
962 
963  private:
964  // Set an incoming argument.
965  void SetParameter(int index, Object* obj) {
966  DCHECK(0 <= index && index < parameters_count());
967  parameters_[index] = obj;
968  }
969 
970  // Set an expression on the expression stack.
971  void SetExpression(int index, Object* obj) {
972  DCHECK(0 <= index && index < expression_count());
973  expression_stack_[index] = obj;
974  }
975 
984 
985  friend class Deoptimizer;
986 };
987 
988 } } // namespace v8::internal
989 
990 #endif // V8_DEOPTIMIZER_H_
#define BASE_EMBEDDED
Definition: allocation.h:45
TranslationBuffer * buffer_
Definition: deoptimizer.h:767
Handle< Object > GetDeferredObject(Isolate *isolate)
ZoneList< uint8_t > contents_
Definition: deoptimizer.h:666
void StoreLiteral(int literal_id)
SlotRef(Isolate *isolate, Object *literal)
Definition: deoptimizer.h:798
void patch_slot_address(intptr_t slot)
Definition: deoptimizer.h:62
static SlotRef ComputeSlotForNextArgument(Translation::Opcode opcode, TranslationIterator *iterator, DeoptimizationInputData *data, JavaScriptFrame *frame)
HeapNumberMaterializationDescriptor(T destination, double value)
Definition: deoptimizer.h:33
void Prepare(Isolate *isolate)
void Add(int32_t value, Zone *zone)
void BeginConstructStubFrame(int literal_id, unsigned height)
Handle< FixedArray > previously_materialized_objects_
Definition: deoptimizer.h:860
void BeginArgumentsAdaptorFrame(int literal_id, unsigned height)
List< Handle< Object > > materialized_objects_
Definition: deoptimizer.h:859
void StoreArgumentsObject(bool args_known, int args_index, int args_length)
void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height)
Handle< ByteArray > CreateByteArray(Factory *factory)
virtual void EnterContext(Context *context)=0
SlotRef(Address addr, SlotRepresentation representation)
Definition: deoptimizer.h:795
void StoreDoubleStackSlot(int index)
void StoreRegister(Register reg)
Handle< Object > GetNext(Isolate *isolate, int level)
void StoreInt32Register(Register reg)
virtual void LeaveContext(Context *context)=0
virtual void VisitFunction(JSFunction *function)=0
void BeginGetterStubFrame(int literal_id)
Handle< Object > literal_
Definition: deoptimizer.h:839
void StoreUint32StackSlot(int index)
ObjectMaterializationDescriptor(Address slot_address, int frame, int length, int duplicate, bool is_args)
Definition: deoptimizer.h:47
void DuplicateObject(int object_index)
static SlotRef NewDeferredObject(int length)
Definition: deoptimizer.h:808
Translation(TranslationBuffer *buffer, int frame_count, int jsframe_count, Zone *zone)
Definition: deoptimizer.h:722
static int NumberOfOperandsFor(Opcode opcode)
TranslationIterator(ByteArray *buffer, int index)
Definition: deoptimizer.h:672
static SlotRef NewArgumentsObject(int length)
Definition: deoptimizer.h:801
void StoreUint32Register(Register reg)
Address slot_address() const
Definition: deoptimizer.h:55
Handle< Object > GetPreviouslyMaterialized(Isolate *isolate, int length)
void StoreStackSlot(int index)
Handle< Object > GetValue(Isolate *isolate)
static Address SlotAddress(JavaScriptFrame *frame, int slot_index)
Definition: deoptimizer.h:876
void BeginArgumentsObject(int args_length)
void StoreDoubleRegister(DoubleRegister reg)
List< SlotRef > slot_refs_
Definition: deoptimizer.h:863
void BeginSetterStubFrame(int literal_id)
static SlotRef NewDuplicateObject(int id)
Definition: deoptimizer.h:817
SlotRepresentation Representation()
Definition: deoptimizer.h:815
void BeginCapturedObject(int length)
void Finish(Isolate *isolate)
SlotRefValueBuilder(JavaScriptFrame *frame, int inlined_frame_index, int formal_parameter_count)
SlotRepresentation representation_
Definition: deoptimizer.h:840
void StoreInt32StackSlot(int index)
virtual ~OptimizedFunctionVisitor()
Definition: deoptimizer.h:77
void Iterate(ObjectVisitor *v)
DeoptimizedFrameInfo(Deoptimizer *deoptimizer, int frame_index, bool has_arguments_adaptor, bool has_construct_stub)
Object * GetExpression(int index)
Definition: deoptimizer.h:954
Object * GetParameter(int index)
Definition: deoptimizer.h:948
void SetParameter(int index, Object *obj)
Definition: deoptimizer.h:965
void SetExpression(int index, Object *obj)
Definition: deoptimizer.h:971
MemoryChunk * deopt_entry_code_[Deoptimizer::kBailoutTypesWithCodeEntry]
Definition: deoptimizer.h:644
int deopt_entry_code_entries_[Deoptimizer::kBailoutTypesWithCodeEntry]
Definition: deoptimizer.h:643
DeoptimizerData(MemoryAllocator *allocator)
Definition: deoptimizer.cc:34
DeoptimizedFrameInfo * deoptimized_frame_info_
Definition: deoptimizer.h:646
MemoryAllocator * allocator_
Definition: deoptimizer.h:642
void Iterate(ObjectVisitor *v)
Definition: deoptimizer.cc:53
DISALLOW_COPY_AND_ASSIGN(DeoptimizerData)
EntryGenerator(MacroAssembler *masm, BailoutType type)
Definition: deoptimizer.h:252
TableEntryGenerator(MacroAssembler *masm, BailoutType type, int count)
Definition: deoptimizer.h:272
unsigned ComputeInputFrameSize() const
void DoComputeAccessorStubFrame(TranslationIterator *iterator, int frame_index, bool is_setter_stub_frame)
List< Handle< Object > > * materialized_objects_
Definition: deoptimizer.h:441
static Deoptimizer * Grab(Isolate *isolate)
Definition: deoptimizer.cc:111
Handle< Object > MaterializeNextHeapObject()
static void MarkAllCodeForContext(Context *native_context)
Definition: deoptimizer.cc:492
static const int kBailoutTypesWithCodeEntry
Definition: deoptimizer.h:102
int ConvertJSFrameIndexToFrameIndex(int jsframe_index)
Definition: deoptimizer.cc:120
void AddObjectStart(intptr_t slot_address, int argc, bool is_arguments)
Code * FindOptimizedCode(JSFunction *function, Code *optimized_code)
Definition: deoptimizer.cc:618
void MaterializeHeapObjects(JavaScriptFrameIterator *it)
static int has_alignment_padding_offset()
Definition: deoptimizer.h:241
void AddDoubleValue(intptr_t slot_address, double value)
static int output_offset()
Definition: deoptimizer.h:239
bool ArgumentsObjectIsAdapted(int object_index)
Definition: deoptimizer.h:350
static void EnsureRelocSpaceForLazyDeoptimization(Handle< Code > code)
void MaterializeHeapNumbersForDebuggerInspectableFrame(Address parameters_top, uint32_t parameters_size, Address expressions_top, uint32_t expressions_size, DeoptimizedFrameInfo *info)
static void ComputeOutputFrames(Deoptimizer *deoptimizer)
Definition: deoptimizer.cc:515
static Deoptimizer * New(JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Isolate *isolate)
Definition: deoptimizer.cc:78
List< Handle< Object > > * materialized_values_
Definition: deoptimizer.h:440
static const int table_entry_size_
Definition: deoptimizer.h:451
unsigned ComputeFixedSize(JSFunction *function) const
Object * ComputeLiteral(int index) const
static void DeoptimizeFunction(JSFunction *function)
Definition: deoptimizer.cc:503
void CopyDoubleRegisters(FrameDescription *output_frame)
void AddObjectDoubleValue(double value)
Deoptimizer(Isolate *isolate, JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Code *optimized_code)
Definition: deoptimizer.cc:548
static void GenerateDeoptimizationEntries(MacroAssembler *masm, int count, BailoutType type)
Definition: deoptimizer.cc:232
void DoTranslateCommand(TranslationIterator *iterator, int frame_index, unsigned output_offset)
Code * FindDeoptimizingCode(Address addr)
Definition: deoptimizer.cc:60
List< ObjectMaterializationDescriptor > deferred_objects_
Definition: deoptimizer.h:427
unsigned ComputeOutgoingArgumentSize() const
List< Handle< JSFunction > > jsframe_functions_
Definition: deoptimizer.h:436
static Address GetDeoptimizationEntry(Isolate *isolate, int id, BailoutType type, GetEntryMode mode=ENSURE_ENTRY_CODE)
Definition: deoptimizer.cc:672
static void DeoptimizeGlobalObject(JSObject *object)
Definition: deoptimizer.cc:470
Handle< FixedArray > previously_materialized_objects_
Definition: deoptimizer.h:432
List< bool > jsframe_has_adapted_arguments_
Definition: deoptimizer.h:437
static void EnsureCodeForDeoptimizationEntry(Isolate *isolate, BailoutType type, int max_entry_id)
static const char * MessageFor(BailoutType type)
Definition: deoptimizer.cc:536
static void PatchCodeForDeoptimization(Isolate *isolate, Code *code)
static DeoptimizedFrameInfo * DebuggerInspectableFrame(JavaScriptFrame *frame, int jsframe_index, Isolate *isolate)
Definition: deoptimizer.cc:136
static void VisitAllOptimizedFunctions(Isolate *isolate, OptimizedFunctionVisitor *visitor)
Definition: deoptimizer.cc:284
static bool TraceEnabledFor(BailoutType deopt_type, StackFrame::Type frame_type)
Definition: deoptimizer.cc:520
static const int kNotDeoptimizationEntry
Definition: deoptimizer.h:247
static void DeoptimizeAll(Isolate *isolate)
Definition: deoptimizer.cc:437
static int output_count_offset()
Definition: deoptimizer.h:236
static void VisitAllOptimizedFunctionsForContext(Context *context, OptimizedFunctionVisitor *visitor)
Definition: deoptimizer.cc:240
static const int kMaxNumberOfEntries
Definition: deoptimizer.h:296
void DoComputeCompiledStubFrame(TranslationIterator *iterator, int frame_index)
static void DeoptimizeMarkedCode(Isolate *isolate)
Definition: deoptimizer.cc:454
void SetPlatformCompiledStubRegisters(FrameDescription *output_frame, CodeStubDescriptor *desc)
Handle< Code > compiled_code() const
Definition: deoptimizer.h:150
static int GetDeoptimizedCodeCount(Isolate *isolate)
Definition: deoptimizer.cc:729
Handle< JSFunction > ArgumentsObjectFunction(int object_index)
Definition: deoptimizer.h:356
static int GetOutputInfo(DeoptimizationOutputData *data, BailoutId node_id, SharedFunctionInfo *shared)
Definition: deoptimizer.cc:707
void DoTranslateObject(TranslationIterator *iterator, int object_index, int field_index)
void DoComputeConstructStubFrame(TranslationIterator *iterator, int frame_index)
void AddObjectDuplication(intptr_t slot, int object_index)
List< HeapNumberMaterializationDescriptor< int > > deferred_objects_double_values_
Definition: deoptimizer.h:426
void DoComputeJSFrame(TranslationIterator *iterator, int frame_index)
Definition: deoptimizer.cc:875
unsigned ComputeIncomingArgumentSize(JSFunction *function) const
FrameDescription ** output_
Definition: deoptimizer.h:421
bool HasAlignmentPadding(JSFunction *function)
List< Object * > deferred_objects_tagged_values_
Definition: deoptimizer.h:424
FrameDescription * input_
Definition: deoptimizer.h:415
BailoutType bailout_type() const
Definition: deoptimizer.h:151
static void DeoptimizeMarkedCodeForContext(Context *native_context)
Definition: deoptimizer.cc:301
static const int kMinNumberOfEntries
Definition: deoptimizer.h:295
CodeTracer::Scope * trace_scope_
Definition: deoptimizer.h:449
Handle< Object > MaterializeNextValue()
Isolate * isolate() const
Definition: deoptimizer.h:292
void FillInputFrame(Address tos, JavaScriptFrame *frame)
void DoTranslateObjectAndSkip(TranslationIterator *iterator)
static size_t GetMaxDeoptTableSize()
Definition: deoptimizer.cc:101
static int GetDeoptimizationId(Isolate *isolate, Address addr, BailoutType type)
Definition: deoptimizer.cc:690
List< HeapNumberMaterializationDescriptor< Address > > deferred_heap_numbers_
Definition: deoptimizer.h:428
void AddObjectTaggedValue(intptr_t value)
void DoComputeArgumentsAdaptorFrame(TranslationIterator *iterator, int frame_index)
static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo *info, Isolate *isolate)
Definition: deoptimizer.cc:224
unsigned GetOffsetFromSlotIndex(int slot_index)
void SetCallerFp(unsigned offset, intptr_t value)
uint32_t GetFrameSize() const
Definition: deoptimizer.h:477
void SetTop(intptr_t top)
Definition: deoptimizer.h:534
double double_registers_[DoubleRegister::kMaxNumRegisters]
Definition: deoptimizer.h:607
void SetContext(intptr_t context)
Definition: deoptimizer.h:543
void SetCallerConstantPool(unsigned offset, intptr_t value)
intptr_t * GetFrameSlotPointer(unsigned offset)
Definition: deoptimizer.h:624
static const uint32_t kZapUint32
Definition: deoptimizer.h:599
intptr_t registers_[Register::kNumRegisters]
Definition: deoptimizer.h:606
JSFunction * GetFunction() const
Definition: deoptimizer.h:482
intptr_t GetConstantPool() const
Definition: deoptimizer.h:545
Object * GetExpression(int index)
double GetDoubleFrameSlot(unsigned offset)
Definition: deoptimizer.h:490
Object * GetParameter(int index)
void SetFrameType(StackFrame::Type type)
Definition: deoptimizer.h:556
FrameDescription(uint32_t frame_size, JSFunction *function)
void SetConstantPool(intptr_t constant_pool)
Definition: deoptimizer.h:546
double GetDoubleRegister(unsigned n) const
Definition: deoptimizer.h:518
StackFrame::Type GetFrameType() const
Definition: deoptimizer.h:555
intptr_t GetFrameSlot(unsigned offset)
Definition: deoptimizer.h:486
static int double_registers_offset()
Definition: deoptimizer.h:574
void SetRegister(unsigned n, intptr_t value)
Definition: deoptimizer.h:523
intptr_t GetRegister(unsigned n) const
Definition: deoptimizer.h:505
void SetCallerPc(unsigned offset, intptr_t value)
void SetFrameSlot(unsigned offset, intptr_t value)
Definition: deoptimizer.h:495
void SetContinuation(intptr_t pc)
Definition: deoptimizer.h:553
void SetDoubleRegister(unsigned n, double value)
Definition: deoptimizer.h:528
T & at(int i) const
Definition: list.h:69
void Set(Address fp, Handle< FixedArray > materialized_objects)
Handle< FixedArray > EnsureStackEntries(int size)
Handle< FixedArray > Get(Address fp)
Handle< FixedArray > GetStackEntries()
MaterializedObjectStore(Isolate *isolate)
Definition: deoptimizer.h:891
#define DECLARE_TRANSLATION_OPCODE_ENUM(item)
Definition: deoptimizer.h:715
#define TRANSLATION_OPCODE_LIST(V)
Definition: deoptimizer.h:691
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
#define OFFSET_OF(type, field)
Definition: macros.h:22
#define arraysize(array)
Definition: macros.h:86
int int32_t
Definition: unicode.cc:24
const int kPointerSize
Definition: globals.h:129
TypeImpl< ZoneTypeConfig > Type
const Register fp
bool CStringEquals(const char *s1, const char *s2)
Definition: utils.h:31
const Register pc
byte * Address
Definition: globals.h:101
static double read_double_value(Address p)
Definition: deoptimizer.h:19
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define LAST(x)
Definition: parser.h:210
bool IsEquivalentTo(const JumpTableEntry &other) const
Definition: deoptimizer.h:130
JumpTableEntry(Address entry, const Reason &the_reason, Deoptimizer::BailoutType type, bool frame)
Definition: deoptimizer.h:122
Deoptimizer::BailoutType bailout_type
Definition: deoptimizer.h:139
Reason(int r, const char *m, const char *d)
Definition: deoptimizer.h:105
bool operator!=(const Reason &other) const
Definition: deoptimizer.h:114
bool operator==(const Reason &other) const
Definition: deoptimizer.h:108
static const int kMaxNumRegisters
static const int kNumRegisters
Definition: assembler-arm.h:95
#define T(name, string, precedence)
Definition: token.cc:25