v8  3.11.10(node0.8.26)
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 OptimizedFunctionVisitor BASE_EMBEDDED {
61  public:
63 
64  // Function which is called before iteration of any optimized functions
65  // from given global context.
66  virtual void EnterContext(Context* context) = 0;
67 
68  virtual void VisitFunction(JSFunction* function) = 0;
69 
70  // Function which is called after iteration of all optimized functions
71  // from given global context.
72  virtual void LeaveContext(Context* context) = 0;
73 };
74 
75 
76 class Deoptimizer;
77 
78 
80  public:
83 
84 #ifdef ENABLE_DEBUGGER_SUPPORT
85  void Iterate(ObjectVisitor* v);
86 #endif
87 
88  private:
89  MemoryChunk* eager_deoptimization_entry_code_;
90  MemoryChunk* lazy_deoptimization_entry_code_;
91  Deoptimizer* current_;
92 
93 #ifdef ENABLE_DEBUGGER_SUPPORT
94  DeoptimizedFrameInfo* deoptimized_frame_info_;
95 #endif
96 
97  // List of deoptimized code which still have references from active stack
98  // frames. These code objects are needed by the deoptimizer when deoptimizing
99  // a frame for which the code object for the function function has been
100  // changed from the code present when deoptimizing was done.
101  DeoptimizingCodeListNode* deoptimizing_code_list_;
102 
103  friend class Deoptimizer;
104 
106 };
107 
108 
109 class Deoptimizer : public Malloced {
110  public:
111  enum BailoutType {
115  // This last bailout type is not really a bailout, but used by the
116  // debugger to deoptimize stack frames to allow inspection.
118  };
119 
120  int output_count() const { return output_count_; }
121 
122  // Number of created JS frames. Not all created frames are necessarily JS.
123  int jsframe_count() const { return jsframe_count_; }
124 
125  static Deoptimizer* New(JSFunction* function,
127  unsigned bailout_id,
128  Address from,
129  int fp_to_sp_delta,
130  Isolate* isolate);
131  static Deoptimizer* Grab(Isolate* isolate);
132 
133 #ifdef ENABLE_DEBUGGER_SUPPORT
134  // The returned object with information on the optimized frame needs to be
135  // freed before another one can be generated.
136  static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame,
137  int jsframe_index,
138  Isolate* isolate);
139  static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
140  Isolate* isolate);
141 #endif
142 
143  // Makes sure that there is enough room in the relocation
144  // information of a code object to perform lazy deoptimization
145  // patching. If there is not enough room a new relocation
146  // information object is allocated and comments are added until it
147  // is big enough.
149 
150  // Deoptimize the function now. Its current optimized code will never be run
151  // again and any activations of the optimized code will get deoptimized when
152  // execution returns.
153  static void DeoptimizeFunction(JSFunction* function);
154 
155  // Deoptimize all functions in the heap.
156  static void DeoptimizeAll();
157 
158  static void DeoptimizeGlobalObject(JSObject* object);
159 
161  Context* context, OptimizedFunctionVisitor* visitor);
162 
164  JSObject* object, OptimizedFunctionVisitor* visitor);
165 
166  static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor* visitor);
167 
168  // The size in bytes of the code required at a lazy deopt patch site.
169  static int patch_size();
170 
171  // Patch all stack guard checks in the unoptimized code to
172  // unconditionally call replacement_code.
173  static void PatchStackCheckCode(Code* unoptimized_code,
174  Code* check_code,
175  Code* replacement_code);
176 
177  // Patch stack guard check at instruction before pc_after in
178  // the unoptimized code to unconditionally call replacement_code.
179  static void PatchStackCheckCodeAt(Code* unoptimized_code,
180  Address pc_after,
181  Code* check_code,
182  Code* replacement_code);
183 
184  // Change all patched stack guard checks in the unoptimized code
185  // back to a normal stack guard check.
186  static void RevertStackCheckCode(Code* unoptimized_code,
187  Code* check_code,
188  Code* replacement_code);
189 
190  // Change all patched stack guard checks in the unoptimized code
191  // back to a normal stack guard check.
192  static void RevertStackCheckCodeAt(Code* unoptimized_code,
193  Address pc_after,
194  Code* check_code,
195  Code* replacement_code);
196 
197  ~Deoptimizer();
198 
199  void MaterializeHeapNumbers();
200 #ifdef ENABLE_DEBUGGER_SUPPORT
201  void MaterializeHeapNumbersForDebuggerInspectableFrame(
202  Address parameters_top,
203  uint32_t parameters_size,
204  Address expressions_top,
205  uint32_t expressions_size,
206  DeoptimizedFrameInfo* info);
207 #endif
208 
209  static void ComputeOutputFrames(Deoptimizer* deoptimizer);
210 
212  static int GetDeoptimizationId(Address addr, BailoutType type);
213  static int GetOutputInfo(DeoptimizationOutputData* data,
214  unsigned node_id,
215  SharedFunctionInfo* shared);
216 
217  // Code generation support.
218  static int input_offset() { return OFFSET_OF(Deoptimizer, input_); }
219  static int output_count_offset() {
220  return OFFSET_OF(Deoptimizer, output_count_);
221  }
222  static int output_offset() { return OFFSET_OF(Deoptimizer, output_); }
223 
225  return OFFSET_OF(Deoptimizer, has_alignment_padding_);
226  }
227 
228  static int GetDeoptimizedCodeCount(Isolate* isolate);
229 
230  static const int kNotDeoptimizationEntry = -1;
231 
232  // Generators for the deoptimization entry code.
233  class EntryGenerator BASE_EMBEDDED {
234  public:
236  : masm_(masm), type_(type) { }
237  virtual ~EntryGenerator() { }
238 
239  void Generate();
240 
241  protected:
242  MacroAssembler* masm() const { return masm_; }
243  BailoutType type() const { return type_; }
244 
245  virtual void GeneratePrologue() { }
246 
247  private:
248  MacroAssembler* masm_;
250  };
251 
252  class TableEntryGenerator : public EntryGenerator {
253  public:
255  : EntryGenerator(masm, type), count_(count) { }
256 
257  protected:
258  virtual void GeneratePrologue();
259 
260  private:
261  int count() const { return count_; }
262 
263  int count_;
264  };
265 
266  int ConvertJSFrameIndexToFrameIndex(int jsframe_index);
267 
268  private:
269  static const int kNumberOfEntries = 16384;
270 
271  Deoptimizer(Isolate* isolate,
272  JSFunction* function,
274  unsigned bailout_id,
275  Address from,
276  int fp_to_sp_delta,
277  Code* optimized_code);
278  void DeleteFrameDescriptions();
279 
280  void DoComputeOutputFrames();
281  void DoComputeOsrOutputFrame();
282  void DoComputeJSFrame(TranslationIterator* iterator, int frame_index);
283  void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
284  int frame_index);
285  void DoComputeConstructStubFrame(TranslationIterator* iterator,
286  int frame_index);
287  void DoTranslateCommand(TranslationIterator* iterator,
288  int frame_index,
289  unsigned output_offset);
290  // Translate a command for OSR. Updates the input offset to be used for
291  // the next command. Returns false if translation of the command failed
292  // (e.g., a number conversion failed) and may or may not have updated the
293  // input offset.
294  bool DoOsrTranslateCommand(TranslationIterator* iterator,
295  int* input_offset);
296 
297  unsigned ComputeInputFrameSize() const;
298  unsigned ComputeFixedSize(JSFunction* function) const;
299 
300  unsigned ComputeIncomingArgumentSize(JSFunction* function) const;
301  unsigned ComputeOutgoingArgumentSize() const;
302 
303  Object* ComputeLiteral(int index) const;
304 
305  void AddDoubleValue(intptr_t slot_address, double value);
306 
307  static MemoryChunk* CreateCode(BailoutType type);
308  static void GenerateDeoptimizationEntries(
309  MacroAssembler* masm, int count, BailoutType type);
310 
311  // Weak handle callback for deoptimizing code objects.
312  static void HandleWeakDeoptimizedCode(
313  v8::Persistent<v8::Value> obj, void* data);
314  static Code* FindDeoptimizingCodeFromAddress(Address addr);
315  static void RemoveDeoptimizingCode(Code* code);
316 
317  // Fill the input from from a JavaScript frame. This is used when
318  // the debugger needs to inspect an optimized frame. For normal
319  // deoptimizations the input frame is filled in generated code.
320  void FillInputFrame(Address tos, JavaScriptFrame* frame);
321 
322  Isolate* isolate_;
323  JSFunction* function_;
324  Code* optimized_code_;
325  unsigned bailout_id_;
326  BailoutType bailout_type_;
327  Address from_;
328  int fp_to_sp_delta_;
329  int has_alignment_padding_;
330 
331  // Input frame description.
332  FrameDescription* input_;
333  // Number of output frames.
334  int output_count_;
335  // Number of output js frames.
336  int jsframe_count_;
337  // Array of output frame descriptions.
338  FrameDescription** output_;
339 
340  List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_;
341 
342  static const int table_entry_size_;
343 
344  friend class FrameDescription;
346  friend class DeoptimizedFrameInfo;
347 };
348 
349 
351  public:
352  FrameDescription(uint32_t frame_size,
353  JSFunction* function);
354 
355  void* operator new(size_t size, uint32_t frame_size) {
356  // Subtracts kPointerSize, as the member frame_content_ already supplies
357  // the first element of the area to store the frame.
358  return malloc(size + frame_size - kPointerSize);
359  }
360 
361  void operator delete(void* pointer, uint32_t frame_size) {
362  free(pointer);
363  }
364 
365  void operator delete(void* description) {
366  free(description);
367  }
368 
369  uint32_t GetFrameSize() const {
370  ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_);
371  return static_cast<uint32_t>(frame_size_);
372  }
373 
374  JSFunction* GetFunction() const { return function_; }
375 
376  unsigned GetOffsetFromSlotIndex(int slot_index);
377 
378  intptr_t GetFrameSlot(unsigned offset) {
379  return *GetFrameSlotPointer(offset);
380  }
381 
382  double GetDoubleFrameSlot(unsigned offset) {
383  intptr_t* ptr = GetFrameSlotPointer(offset);
384 #if V8_TARGET_ARCH_MIPS
385  // Prevent gcc from using load-double (mips ldc1) on (possibly)
386  // non-64-bit aligned double. Uses two lwc1 instructions.
387  union conversion {
388  double d;
389  uint32_t u[2];
390  } c;
391  c.u[0] = *reinterpret_cast<uint32_t*>(ptr);
392  c.u[1] = *(reinterpret_cast<uint32_t*>(ptr) + 1);
393  return c.d;
394 #else
395  return *reinterpret_cast<double*>(ptr);
396 #endif
397  }
398 
399  void SetFrameSlot(unsigned offset, intptr_t value) {
400  *GetFrameSlotPointer(offset) = value;
401  }
402 
403  intptr_t GetRegister(unsigned n) const {
404  ASSERT(n < ARRAY_SIZE(registers_));
405  return registers_[n];
406  }
407 
408  double GetDoubleRegister(unsigned n) const {
409  ASSERT(n < ARRAY_SIZE(double_registers_));
410  return double_registers_[n];
411  }
412 
413  void SetRegister(unsigned n, intptr_t value) {
414  ASSERT(n < ARRAY_SIZE(registers_));
415  registers_[n] = value;
416  }
417 
418  void SetDoubleRegister(unsigned n, double value) {
419  ASSERT(n < ARRAY_SIZE(double_registers_));
420  double_registers_[n] = value;
421  }
422 
423  intptr_t GetTop() const { return top_; }
424  void SetTop(intptr_t top) { top_ = top; }
425 
426  intptr_t GetPc() const { return pc_; }
427  void SetPc(intptr_t pc) { pc_ = pc; }
428 
429  intptr_t GetFp() const { return fp_; }
430  void SetFp(intptr_t fp) { fp_ = fp; }
431 
432  intptr_t GetContext() const { return context_; }
433  void SetContext(intptr_t context) { context_ = context; }
434 
435  Smi* GetState() const { return state_; }
436  void SetState(Smi* state) { state_ = state; }
437 
438  void SetContinuation(intptr_t pc) { continuation_ = pc; }
439 
440  StackFrame::Type GetFrameType() const { return type_; }
441  void SetFrameType(StackFrame::Type type) { type_ = type; }
442 
443  // Get the incoming arguments count.
445 
446  // Get a parameter value for an unoptimized frame.
447  Object* GetParameter(int index);
448 
449  // Get the expression stack height for a unoptimized frame.
450  unsigned GetExpressionCount();
451 
452  // Get the expression stack value for an unoptimized frame.
453  Object* GetExpression(int index);
454 
455  static int registers_offset() {
456  return OFFSET_OF(FrameDescription, registers_);
457  }
458 
459  static int double_registers_offset() {
460  return OFFSET_OF(FrameDescription, double_registers_);
461  }
462 
463  static int frame_size_offset() {
464  return OFFSET_OF(FrameDescription, frame_size_);
465  }
466 
467  static int pc_offset() {
468  return OFFSET_OF(FrameDescription, pc_);
469  }
470 
471  static int state_offset() {
472  return OFFSET_OF(FrameDescription, state_);
473  }
474 
475  static int continuation_offset() {
476  return OFFSET_OF(FrameDescription, continuation_);
477  }
478 
479  static int frame_content_offset() {
480  return OFFSET_OF(FrameDescription, frame_content_);
481  }
482 
483  private:
484  static const uint32_t kZapUint32 = 0xbeeddead;
485 
486  // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to
487  // keep the variable-size array frame_content_ of type intptr_t at
488  // the end of the structure aligned.
489  uintptr_t frame_size_; // Number of bytes.
490  JSFunction* function_;
491  intptr_t registers_[Register::kNumRegisters];
492  double double_registers_[DoubleRegister::kNumAllocatableRegisters];
493  intptr_t top_;
494  intptr_t pc_;
495  intptr_t fp_;
496  intptr_t context_;
497  StackFrame::Type type_;
498  Smi* state_;
499 #ifdef DEBUG
500  Code::Kind kind_;
501 #endif
502 
503  // Continuation is the PC where the execution continues after
504  // deoptimizing.
505  intptr_t continuation_;
506 
507  // This must be at the end of the object as the object is allocated larger
508  // than it's definition indicate to extend this array.
509  intptr_t frame_content_[1];
510 
511  intptr_t* GetFrameSlotPointer(unsigned offset) {
512  ASSERT(offset < frame_size_);
513  return reinterpret_cast<intptr_t*>(
514  reinterpret_cast<Address>(this) + frame_content_offset() + offset);
515  }
516 
517  int ComputeFixedSize();
518 };
519 
520 
521 class TranslationBuffer BASE_EMBEDDED {
522  public:
523  explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { }
524 
525  int CurrentIndex() const { return contents_.length(); }
526  void Add(int32_t value, Zone* zone);
527 
528  Handle<ByteArray> CreateByteArray();
529 
530  private:
531  ZoneList<uint8_t> contents_;
532 };
533 
534 
535 class TranslationIterator BASE_EMBEDDED {
536  public:
537  TranslationIterator(ByteArray* buffer, int index)
538  : buffer_(buffer), index_(index) {
539  ASSERT(index >= 0 && index < buffer->length());
540  }
541 
542  int32_t Next();
543 
544  bool HasNext() const { return index_ < buffer_->length(); }
545 
546  void Skip(int n) {
547  for (int i = 0; i < n; i++) Next();
548  }
549 
550  private:
552  int index_;
553 };
554 
555 
556 class Translation BASE_EMBEDDED {
557  public:
558  enum Opcode {
571 
572  // A prefix indicating that the next command is a duplicate of the one
573  // that follows it.
574  DUPLICATE
575  };
576 
577  Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count,
578  Zone* zone)
579  : buffer_(buffer),
580  index_(buffer->CurrentIndex()),
581  zone_(zone) {
582  buffer_->Add(BEGIN, zone);
583  buffer_->Add(frame_count, zone);
584  buffer_->Add(jsframe_count, zone);
585  }
586 
587  int index() const { return index_; }
588 
589  // Commands.
590  void BeginJSFrame(int node_id, int literal_id, unsigned height);
591  void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
592  void BeginConstructStubFrame(int literal_id, unsigned height);
593  void StoreRegister(Register reg);
594  void StoreInt32Register(Register reg);
595  void StoreDoubleRegister(DoubleRegister reg);
596  void StoreStackSlot(int index);
597  void StoreInt32StackSlot(int index);
598  void StoreDoubleStackSlot(int index);
599  void StoreLiteral(int literal_id);
600  void StoreArgumentsObject();
601  void MarkDuplicate();
602 
603  Zone* zone() const { return zone_; }
604 
605  static int NumberOfOperandsFor(Opcode opcode);
606 
607 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
608  static const char* StringFor(Opcode opcode);
609 #endif
610 
611  private:
612  TranslationBuffer* buffer_;
613  int index_;
614  Zone* zone_;
615 };
616 
617 
618 // Linked list holding deoptimizing code objects. The deoptimizing code objects
619 // are kept as weak handles until they are no longer activated on the stack.
621  public:
624 
625  DeoptimizingCodeListNode* next() const { return next_; }
627  Handle<Code> code() const { return code_; }
628 
629  private:
630  // Global (weak) handle to the deoptimizing code object.
631  Handle<Code> code_;
632 
633  // Next pointer for linked list.
635 };
636 
637 
638 class SlotRef BASE_EMBEDDED {
639  public:
645  LITERAL
646  };
647 
649  : addr_(NULL), representation_(UNKNOWN) { }
650 
651  SlotRef(Address addr, SlotRepresentation representation)
652  : addr_(addr), representation_(representation) { }
653 
654  explicit SlotRef(Object* literal)
655  : literal_(literal), representation_(LITERAL) { }
656 
658  switch (representation_) {
659  case TAGGED:
660  return Handle<Object>(Memory::Object_at(addr_));
661 
662  case INT32: {
663  int value = Memory::int32_at(addr_);
664  if (Smi::IsValid(value)) {
665  return Handle<Object>(Smi::FromInt(value));
666  } else {
667  return Isolate::Current()->factory()->NewNumberFromInt(value);
668  }
669  }
670 
671  case DOUBLE: {
672  double value = Memory::double_at(addr_);
673  return Isolate::Current()->factory()->NewNumber(value);
674  }
675 
676  case LITERAL:
677  return literal_;
678 
679  default:
680  UNREACHABLE();
681  return Handle<Object>::null();
682  }
683  }
684 
685  static Vector<SlotRef> ComputeSlotMappingForArguments(
686  JavaScriptFrame* frame,
687  int inlined_frame_index,
689 
690  private:
691  Address addr_;
692  Handle<Object> literal_;
693  SlotRepresentation representation_;
694 
695  static Address SlotAddress(JavaScriptFrame* frame, int slot_index) {
696  if (slot_index >= 0) {
697  const int offset = JavaScriptFrameConstants::kLocal0Offset;
698  return frame->fp() + offset - (slot_index * kPointerSize);
699  } else {
701  return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
702  }
703  }
704 
705  static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator,
706  DeoptimizationInputData* data,
707  JavaScriptFrame* frame);
708 
709  static void ComputeSlotsForArguments(
710  Vector<SlotRef>* args_slots,
711  TranslationIterator* iterator,
712  DeoptimizationInputData* data,
713  JavaScriptFrame* frame);
714 };
715 
716 
717 #ifdef ENABLE_DEBUGGER_SUPPORT
718 // Class used to represent an unoptimized frame when the debugger
719 // needs to inspect a frame that is part of an optimized frame. The
720 // internally used FrameDescription objects are not GC safe so for use
721 // by the debugger frame information is copied to an object of this type.
722 // Represents parameters in unadapted form so their number might mismatch
723 // formal parameter count.
724 class DeoptimizedFrameInfo : public Malloced {
725  public:
726  DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
727  int frame_index,
728  bool has_arguments_adaptor,
729  bool has_construct_stub);
730  virtual ~DeoptimizedFrameInfo();
731 
732  // GC support.
733  void Iterate(ObjectVisitor* v);
734 
735  // Return the number of incoming arguments.
736  int parameters_count() { return parameters_count_; }
737 
738  // Return the height of the expression stack.
739  int expression_count() { return expression_count_; }
740 
741  // Get the frame function.
742  JSFunction* GetFunction() {
743  return function_;
744  }
745 
746  // Check if this frame is preceded by construct stub frame. The bottom-most
747  // inlined frame might still be called by an uninlined construct stub.
748  bool HasConstructStub() {
749  return has_construct_stub_;
750  }
751 
752  // Get an incoming argument.
753  Object* GetParameter(int index) {
754  ASSERT(0 <= index && index < parameters_count());
755  return parameters_[index];
756  }
757 
758  // Get an expression from the expression stack.
759  Object* GetExpression(int index) {
760  ASSERT(0 <= index && index < expression_count());
761  return expression_stack_[index];
762  }
763 
764  int GetSourcePosition() {
765  return source_position_;
766  }
767 
768  private:
769  // Set an incoming argument.
770  void SetParameter(int index, Object* obj) {
771  ASSERT(0 <= index && index < parameters_count());
772  parameters_[index] = obj;
773  }
774 
775  // Set an expression on the expression stack.
776  void SetExpression(int index, Object* obj) {
777  ASSERT(0 <= index && index < expression_count());
778  expression_stack_[index] = obj;
779  }
780 
781  JSFunction* function_;
782  bool has_construct_stub_;
783  int parameters_count_;
784  int expression_count_;
785  Object** parameters_;
786  Object** expression_stack_;
787  int source_position_;
788 
789  friend class Deoptimizer;
790 };
791 #endif
792 
793 } } // namespace v8::internal
794 
795 #endif // V8_DEOPTIMIZER_H_
byte * Address
Definition: globals.h:172
DeoptimizingCodeListNode * next() const
Definition: deoptimizer.h:625
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:973
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:399
static void RevertStackCheckCode(Code *unoptimized_code, Code *check_code, Code *replacement_code)
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kThisPropertyAssignmentsOffset kNeedsAccessCheckBit kIsExpressionBit kHasOnlySimpleThisPropertyAssignments kUsesArguments formal_parameter_count
Definition: objects-inl.h:3755
static void ComputeOutputFrames(Deoptimizer *deoptimizer)
Definition: deoptimizer.cc:339
Address slot_address() const
Definition: deoptimizer.h:51
SlotRef(Object *literal)
Definition: deoptimizer.h:654
int int32_t
Definition: unicode.cc:47
Definition: deoptimizer.h:252
static const int kNumAllocatableRegisters
SlotRef(Address addr, SlotRepresentation representation)
Definition: deoptimizer.h:651
FlagType type_
Definition: flags.cc:1351
#define ASSERT(condition)
Definition: checks.h:270
static void DeoptimizeFunction(JSFunction *function)
static void DeoptimizeAll()
Definition: deoptimizer.cc:249
Handle< Object > GetValue()
Definition: deoptimizer.h:657
double GetDoubleRegister(unsigned n) const
Definition: deoptimizer.h:408
intptr_t GetContext() const
Definition: deoptimizer.h:432
void SetFrameType(StackFrame::Type type)
Definition: deoptimizer.h:441
StringInputBuffer *const buffer_
static const int kNumRegisters
Definition: assembler-arm.h:73
static int double_registers_offset()
Definition: deoptimizer.h:459
MacroAssembler * masm() const
Definition: deoptimizer.h:242
JSFunction * GetFunction() const
Definition: deoptimizer.h:374
static void DeoptimizeGlobalObject(JSObject *object)
Definition: deoptimizer.cc:261
#define UNREACHABLE()
Definition: checks.h:50
static int output_offset()
Definition: deoptimizer.h:222
TableEntryGenerator(MacroAssembler *masm, BailoutType type, int count)
Definition: deoptimizer.h:254
#define OFFSET_OF(type, field)
Definition: globals.h:287
static bool IsValid(intptr_t value)
Definition: objects-inl.h:1051
const int kPointerSize
Definition: globals.h:234
Translation(TranslationBuffer *buffer, int frame_count, int jsframe_count, Zone *zone)
Definition: deoptimizer.h:577
static int32_t & int32_at(Address addr)
Definition: v8memory.h:51
EntryGenerator(MacroAssembler *masm, BailoutType type)
Definition: deoptimizer.h:235
void SetRegister(unsigned n, intptr_t value)
Definition: deoptimizer.h:413
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:321
const Register pc
static int GetDeoptimizedCodeCount(Isolate *isolate)
Definition: deoptimizer.cc:512
void set_next(DeoptimizingCodeListNode *next)
Definition: deoptimizer.h:626
static int GetOutputInfo(DeoptimizationOutputData *data, unsigned node_id, SharedFunctionInfo *shared)
Definition: deoptimizer.cc:486
static void EnsureRelocSpaceForLazyDeoptimization(Handle< 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:369
static void VisitAllOptimizedFunctionsForContext(Context *context, OptimizedFunctionVisitor *visitor)
Definition: deoptimizer.cc:269
void SetContinuation(intptr_t pc)
Definition: deoptimizer.h:438
virtual ~OptimizedFunctionVisitor()
Definition: deoptimizer.h:62
static int output_count_offset()
Definition: deoptimizer.h:219
static void RevertStackCheckCodeAt(Code *unoptimized_code, Address pc_after, Code *check_code, Code *replacement_code)
intptr_t GetFrameSlot(unsigned offset)
Definition: deoptimizer.h:378
friend class DeoptimizedFrameInfo
Definition: deoptimizer.h:346
static Address GetDeoptimizationEntry(int id, BailoutType type)
Definition: deoptimizer.cc:445
TranslationIterator(ByteArray *buffer, int index)
Definition: deoptimizer.h:537
static Deoptimizer * Grab(Isolate *isolate)
Definition: deoptimizer.cc:98
static const int kNotDeoptimizationEntry
Definition: deoptimizer.h:230
static Handle< T > null()
Definition: handles.h:86
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
friend class FrameDescription
Definition: deoptimizer.h:344
StackFrame::Type GetFrameType() const
Definition: deoptimizer.h:440
virtual void GeneratePrologue()
double GetDoubleFrameSlot(unsigned offset)
Definition: deoptimizer.h:382
FrameDescription(uint32_t frame_size, JSFunction *function)
static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor *visitor)
Definition: deoptimizer.cc:305
void SetContext(intptr_t context)
Definition: deoptimizer.h:433
int ConvertJSFrameIndexToFrameIndex(int jsframe_index)
Definition: deoptimizer.cc:108
static void VisitAllOptimizedFunctionsForGlobalObject(JSObject *object, OptimizedFunctionVisitor *visitor)
Definition: deoptimizer.cc:289
const Register fp
intptr_t GetRegister(unsigned n) const
Definition: deoptimizer.h:403
void SetDoubleRegister(unsigned n, double value)
Definition: deoptimizer.h:418
int jsframe_count() const
Definition: deoptimizer.h:123
static int GetDeoptimizationId(Address addr, BailoutType type)
Definition: deoptimizer.cc:466
#define ARRAY_SIZE(a)
Definition: globals.h:295
static void PatchStackCheckCodeAt(Code *unoptimized_code, Address pc_after, Code *check_code, Code *replacement_code)
FlagType type() const
Definition: flags.cc:1358
void SetTop(intptr_t top)
Definition: deoptimizer.h:424
static int has_alignment_padding_offset()
Definition: deoptimizer.h:224
static Deoptimizer * New(JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Isolate *isolate)
Definition: deoptimizer.cc:78
Object * GetExpression(int index)
Object * GetParameter(int index)