13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifndef V8_DEOPTIMIZER_H_
6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define V8_DEOPTIMIZER_H_
7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h"
10b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
11b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
12b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 {
13b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal {
14b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass FrameDescription;
16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TranslationIterator;
173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass DeoptimizedFrameInfo;
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TranslatedState;
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass RegisterValues;
20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TranslatedValue {
22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocation-less getter of the value.
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Returns heap()->arguments_marker() if allocation would be
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // necessary to get the value.
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* GetRawValue() const;
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> GetValue();
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsMaterializedObject() const;
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  friend class TranslatedState;
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  friend class TranslatedFrame;
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Kind {
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kInvalid,
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kTagged,
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kInt32,
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kUInt32,
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kBoolBit,
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kDouble,
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kCapturedObject,    // Object captured by the escape analysis.
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        // The number of nested objects can be obtained
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        // with the DeferredObjectLength() method
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        // (the values of the nested objects follow
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        // this value in the depth-first order.)
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kDuplicatedObject,  // Duplicated object of a deferred object.
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kArgumentsObject    // Arguments object - only used to keep indexing
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        // in sync, it should not be materialized.
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue(TranslatedState* container, Kind kind)
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : kind_(kind), container_(container) {}
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Kind kind() const { return kind_; }
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Handlify();
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int GetChildrenCount() const;
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedValue NewArgumentsObject(TranslatedState* container,
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            int length, int object_index);
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedValue NewDeferredObject(TranslatedState* container,
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           int length, int object_index);
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedValue NewDuplicateObject(TranslatedState* container, int id);
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedValue NewDouble(TranslatedState* container, double value);
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedValue NewInt32(TranslatedState* container, int32_t value);
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedValue NewUInt32(TranslatedState* container, uint32_t value);
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedValue NewBool(TranslatedState* container, uint32_t value);
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedValue NewTagged(TranslatedState* container, Object* literal);
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedValue NewInvalid(TranslatedState* container);
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate() const;
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void MaterializeSimple();
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Kind kind_;
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedState* container_;  // This is only needed for materialization of
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                // objects and constructing handles (to get
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                // to the isolate).
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaybeHandle<Object> value_;  // Before handlification, this is always null,
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               // after materialization it is never null,
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               // in between it is only null if the value needs
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               // to be materialized.
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct MaterializedObjectInfo {
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int id_;
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int length_;  // Applies only to kArgumentsObject or kCapturedObject kinds.
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  union {
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // kind kTagged. After handlification it is always nullptr.
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object* raw_literal_;
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // kind is kUInt32 or kBoolBit.
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t uint32_value_;
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // kind is kInt32.
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t int32_value_;
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // kind is kDouble
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    double double_value_;
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // kind is kDuplicatedObject or kArgumentsObject or kCapturedObject.
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MaterializedObjectInfo materialization_info_;
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Checked accessors for the union members.
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* raw_literal() const;
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t int32_value() const;
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t uint32_value() const;
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double double_value() const;
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int object_length() const;
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int object_index() const;
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TranslatedFrame {
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Kind {
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kFunction,
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kInterpretedFunction,
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kGetter,
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kSetter,
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kArgumentsAdaptor,
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kConstructStub,
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kCompiledStub,
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kInvalid
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int GetValueCount();
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Kind kind() const { return kind_; }
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId node_id() const { return node_id_; }
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int height() const { return height_; }
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class iterator {
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   public:
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator& operator++() {
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AdvanceIterator(&position_);
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return *this;
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator operator++(int) {
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      iterator original(position_);
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AdvanceIterator(&position_);
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return original;
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool operator==(const iterator& other) const {
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return position_ == other.position_;
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool operator!=(const iterator& other) const { return !(*this == other); }
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedValue& operator*() { return (*position_); }
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedValue* operator->() { return &(*position_); }
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   private:
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    friend TranslatedFrame;
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    explicit iterator(std::deque<TranslatedValue>::iterator position)
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        : position_(position) {}
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    std::deque<TranslatedValue>::iterator position_;
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef TranslatedValue& reference;
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef TranslatedValue const& const_reference;
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  iterator begin() { return iterator(values_.begin()); }
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  iterator end() { return iterator(values_.end()); }
166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  reference front() { return values_.front(); }
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const_reference front() const { return values_.front(); }
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  friend class TranslatedState;
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Constructor static methods.
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedFrame JSFrame(BailoutId node_id,
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 SharedFunctionInfo* shared_info, int height);
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedFrame InterpretedFrame(BailoutId bytecode_offset,
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          SharedFunctionInfo* shared_info,
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          int height);
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedFrame AccessorFrame(Kind kind,
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       SharedFunctionInfo* shared_info);
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedFrame ArgumentsAdaptorFrame(SharedFunctionInfo* shared_info,
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               int height);
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedFrame ConstructStubFrame(SharedFunctionInfo* shared_info,
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            int height);
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedFrame CompiledStubFrame(int height, Isolate* isolate) {
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return TranslatedFrame(kCompiledStub, isolate, nullptr, height);
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static TranslatedFrame InvalidFrame() {
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return TranslatedFrame(kInvalid, nullptr);
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static void AdvanceIterator(std::deque<TranslatedValue>::iterator* iter);
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame(Kind kind, Isolate* isolate,
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  SharedFunctionInfo* shared_info = nullptr, int height = 0)
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : kind_(kind),
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node_id_(BailoutId::None()),
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        raw_shared_info_(shared_info),
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        height_(height),
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_(isolate) {}
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Add(const TranslatedValue& value) { values_.push_back(value); }
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Handlify();
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Kind kind_;
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId node_id_;
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SharedFunctionInfo* raw_shared_info_;
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<SharedFunctionInfo> shared_info_;
210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int height_;
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate_;
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef std::deque<TranslatedValue> ValuesContainer;
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ValuesContainer values_;
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Auxiliary class for translating deoptimization values.
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Typical usage sequence:
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 1. Construct the instance. This will involve reading out the translations
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//    and resolving them to values using the supplied frame pointer and
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//    machine state (registers). This phase is guaranteed not to allocate
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//    and not to use any HandleScope. Any object pointers will be stored raw.
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 2. Handlify pointers. This will convert all the raw pointers to handles.
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 3. Reading out the frame values.
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Note: After the instance is constructed, it is possible to iterate over
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// the values eagerly.
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TranslatedState {
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedState();
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit TranslatedState(JavaScriptFrame* frame);
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Prepare(bool has_adapted_arguments, Address stack_frame_pointer);
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Store newly materialized values into the isolate.
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void StoreMaterializedValuesAndDeopt();
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef std::vector<TranslatedFrame>::iterator iterator;
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  iterator begin() { return frames_.begin(); }
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  iterator end() { return frames_.end(); }
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef std::vector<TranslatedFrame>::const_iterator const_iterator;
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const_iterator begin() const { return frames_.begin(); }
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const_iterator end() const { return frames_.end(); }
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::vector<TranslatedFrame>& frames() { return frames_; }
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* GetArgumentsInfoFromJSFrameIndex(int jsframe_index,
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int* arguments_count);
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate() { return isolate_; }
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Init(Address input_frame_pointer, TranslationIterator* iterator,
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            FixedArray* literal_array, RegisterValues* registers,
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            FILE* trace_file);
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  friend TranslatedValue;
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame CreateNextTranslatedFrame(TranslationIterator* iterator,
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            FixedArray* literal_array,
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            Address fp,
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            FILE* trace_file);
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue CreateNextTranslatedValue(int frame_index, int value_index,
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            TranslationIterator* iterator,
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            FixedArray* literal_array,
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            Address fp,
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            RegisterValues* registers,
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            FILE* trace_file);
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateFromPreviouslyMaterializedObjects();
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> MaterializeAt(int frame_index, int* value_index);
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> MaterializeObjectAt(int object_index);
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool GetAdaptedArguments(Handle<JSObject>* result, int frame_index);
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static uint32_t GetUInt32Slot(Address fp, int slot_index);
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::vector<TranslatedFrame> frames_;
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate_;
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address stack_frame_pointer_;
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool has_adapted_arguments_;
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct ObjectPosition {
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int frame_index_;
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int value_index_;
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::deque<ObjectPosition> object_positions_;
294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass OptimizedFunctionVisitor BASE_EMBEDDED {
298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~OptimizedFunctionVisitor() {}
300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Function which is called before iteration of any optimized functions
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // from given native context.
303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void EnterContext(Context* context) = 0;
304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void VisitFunction(JSFunction* function) = 0;
306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Function which is called after iteration of all optimized functions
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // from given native context.
309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void LeaveContext(Context* context) = 0;
310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DEOPT_MESSAGES_LIST(V)                                                 \
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kAccessCheck, "Access check needed")                                       \
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNoReason, "no reason")                                                    \
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kConstantGlobalVariableAssignment, "Constant global variable assignment")  \
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kConversionOverflow, "conversion overflow")                                \
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kDivisionByZero, "division by zero")                                       \
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kElementsKindUnhandledInKeyedLoadGenericStub,                              \
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "ElementsKind unhandled in KeyedLoadGenericStub")                          \
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kExpectedHeapNumber, "Expected heap number")                               \
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kExpectedSmi, "Expected smi")                                              \
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kForcedDeoptToRuntime, "Forced deopt to runtime")                          \
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kHole, "hole")                                                             \
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kHoleyArrayDespitePackedElements_kindFeedback,                             \
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Holey array despite packed elements_kind feedback")                       \
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kInstanceMigrationFailed, "instance migration failed")                     \
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kInsufficientTypeFeedbackForCallWithArguments,                             \
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Insufficient type feedback for call with arguments")                      \
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation,                 \
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Insufficient type feedback for combined type of binary operation")        \
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kInsufficientTypeFeedbackForGenericNamedAccess,                            \
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Insufficient type feedback for generic named access")                     \
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kInsufficientTypeFeedbackForKeyedLoad,                                     \
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Insufficient type feedback for keyed load")                               \
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kInsufficientTypeFeedbackForKeyedStore,                                    \
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Insufficient type feedback for keyed store")                              \
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kInsufficientTypeFeedbackForLHSOfBinaryOperation,                          \
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Insufficient type feedback for LHS of binary operation")                  \
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kInsufficientTypeFeedbackForRHSOfBinaryOperation,                          \
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Insufficient type feedback for RHS of binary operation")                  \
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kKeyIsNegative, "key is negative")                                         \
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kLiteralsWereDisposed, "literals have been disposed")                      \
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kLostPrecision, "lost precision")                                          \
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kLostPrecisionOrNaN, "lost precision or NaN")                              \
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kMementoFound, "memento found")                                            \
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kMinusZero, "minus zero")                                                  \
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNaN, "NaN")                                                               \
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNegativeKeyEncountered, "Negative key encountered")                       \
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNegativeValue, "negative value")                                          \
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNoCache, "no cache")                                                      \
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNonStrictElementsInKeyedLoadGenericStub,                                  \
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "non-strict elements in KeyedLoadGenericStub")                             \
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNotADateObject, "not a date object")                                      \
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNotAHeapNumber, "not a heap number")                                      \
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNotAHeapNumberUndefinedBoolean, "not a heap number/undefined/true/false") \
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNotAHeapNumberUndefined, "not a heap number/undefined")                   \
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNotAJavaScriptObject, "not a JavaScript object")                          \
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNotASmi, "not a Smi")                                                     \
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kNull, "null")                                                             \
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kOutOfBounds, "out of bounds")                                             \
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kOutsideOfRange, "Outside of range")                                       \
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kOverflow, "overflow")                                                     \
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kProxy, "proxy")                                                           \
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kReceiverWasAGlobalObject, "receiver was a global object")                 \
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kSmi, "Smi")                                                               \
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kTooManyArguments, "too many arguments")                                   \
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kTooManyUndetectableTypes, "Too many undetectable types")                  \
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kTracingElementsTransitions, "Tracing elements transitions")               \
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kTypeMismatchBetweenFeedbackAndConstant,                                   \
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Type mismatch between feedback and constant")                             \
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUndefined, "undefined")                                                   \
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUnexpectedCellContentsInConstantGlobalStore,                              \
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Unexpected cell contents in constant global store")                       \
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUnexpectedCellContentsInGlobalStore,                                      \
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Unexpected cell contents in global store")                                \
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUnexpectedObject, "unexpected object")                                    \
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUnexpectedRHSOfBinaryOperation, "Unexpected RHS of binary operation")     \
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUninitializedBoilerplateInFastClone,                                      \
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Uninitialized boilerplate in fast clone")                                 \
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUninitializedBoilerplateLiterals, "Uninitialized boilerplate literals")   \
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUnknownMapInPolymorphicAccess, "Unknown map in polymorphic access")       \
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUnknownMapInPolymorphicCall, "Unknown map in polymorphic call")           \
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUnknownMapInPolymorphicElementAccess,                                     \
385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "Unknown map in polymorphic element access")                               \
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUnknownMap, "Unknown map")                                                \
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kValueMismatch, "value mismatch")                                          \
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kWrongInstanceType, "wrong instance type")                                 \
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kWrongMap, "wrong map")                                                    \
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUndefinedOrNullInForIn, "null or undefined in for-in")                    \
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(kUndefinedOrNullInToObject, "null or undefined in ToObject")
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass Deoptimizer : public Malloced {
395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  enum BailoutType {
397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    EAGER,
398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    LAZY,
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SOFT,
4003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // This last bailout type is not really a bailout, but used by the
4013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // debugger to deoptimize stack frames to allow inspection.
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DEBUGGER,
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kBailoutTypesWithCodeEntry = SOFT + 1
404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DEOPT_MESSAGES_CONSTANTS(C, T) C,
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum DeoptReason {
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_CONSTANTS) kLastDeoptReason
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DEOPT_MESSAGES_CONSTANTS
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const char* GetDeoptReason(DeoptReason deopt_reason);
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct DeoptInfo {
414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DeoptInfo(SourcePosition position, const char* m, DeoptReason d)
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        : position(position), mnemonic(m), deopt_reason(d), inlining_id(0) {}
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SourcePosition position;
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const char* mnemonic;
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DeoptReason deopt_reason;
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int inlining_id;
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static DeoptInfo GetDeoptInfo(Code* code, byte* from);
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  struct JumpTableEntry : public ZoneObject {
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    inline JumpTableEntry(Address entry, const DeoptInfo& deopt_info,
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          Deoptimizer::BailoutType type, bool frame)
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : label(),
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          address(entry),
430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          deopt_info(deopt_info),
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          bailout_type(type),
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          needs_frame(frame) {}
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool IsEquivalentTo(const JumpTableEntry& other) const {
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return address == other.address && bailout_type == other.bailout_type &&
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             needs_frame == other.needs_frame;
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label label;
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Address address;
441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DeoptInfo deopt_info;
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Deoptimizer::BailoutType bailout_type;
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool needs_frame;
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool TraceEnabledFor(BailoutType deopt_type,
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              StackFrame::Type frame_type);
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const char* MessageFor(BailoutType type);
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int output_count() const { return output_count_; }
451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSFunction> function() const { return Handle<JSFunction>(function_); }
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> compiled_code() const { return Handle<Code>(compiled_code_); }
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutType bailout_type() const { return bailout_type_; }
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Number of created JS frames. Not all created frames are necessarily JS.
4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int jsframe_count() const { return jsframe_count_; }
4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static Deoptimizer* New(JSFunction* function,
460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          BailoutType type,
461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          unsigned bailout_id,
462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          Address from,
46344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                          int fp_to_sp_delta,
46444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                          Isolate* isolate);
46544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static Deoptimizer* Grab(Isolate* isolate);
46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
4673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // The returned object with information on the optimized frame needs to be
4683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // freed before another one can be generated.
4693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame,
4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                        int jsframe_index,
4713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                        Isolate* isolate);
4723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
4733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                             Isolate* isolate);
4743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Makes sure that there is enough room in the relocation
47644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // information of a code object to perform lazy deoptimization
47744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // patching. If there is not enough room a new relocation
47844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // information object is allocated and comments are added until it
47944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // is big enough.
48044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code);
481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Deoptimize the function now. Its current optimized code will never be run
483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // again and any activations of the optimized code will get deoptimized when
484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // execution returns.
485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static void DeoptimizeFunction(JSFunction* function);
486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Deoptimize all code in the given isolate.
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void DeoptimizeAll(Isolate* isolate);
489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Deoptimizes all optimized code that has been previously marked
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (via code->set_marked_for_deoptimization) and unlinks all functions that
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // refer to that code.
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void DeoptimizeMarkedCode(Isolate* isolate);
494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit all the known optimized functions in a given isolate.
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void VisitAllOptimizedFunctions(
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Isolate* isolate, OptimizedFunctionVisitor* visitor);
498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // The size in bytes of the code required at a lazy deopt patch site.
5001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static int patch_size();
5011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ~Deoptimizer();
503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MaterializeHeapObjects(JavaScriptFrameIterator* it);
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void MaterializeHeapNumbersForDebuggerInspectableFrame(
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int frame_index, int parameter_count, int expression_count,
5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      DeoptimizedFrameInfo* info);
509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static void ComputeOutputFrames(Deoptimizer* deoptimizer);
511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum GetEntryMode {
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CALCULATE_ENTRY_ADDRESS,
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ENSURE_ENTRY_CODE
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Address GetDeoptimizationEntry(
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Isolate* isolate,
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int id,
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BailoutType type,
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      GetEntryMode mode = ENSURE_ENTRY_CODE);
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int GetDeoptimizationId(Isolate* isolate,
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Address addr,
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 BailoutType type);
5279fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  static int GetOutputInfo(DeoptimizationOutputData* data,
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           BailoutId node_id,
5299fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                           SharedFunctionInfo* shared);
530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Code generation support.
532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int input_offset() { return OFFSET_OF(Deoptimizer, input_); }
533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int output_count_offset() {
534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return OFFSET_OF(Deoptimizer, output_count_);
535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int output_offset() { return OFFSET_OF(Deoptimizer, output_); }
537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int has_alignment_padding_offset() {
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return OFFSET_OF(Deoptimizer, has_alignment_padding_);
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static int GetDeoptimizedCodeCount(Isolate* isolate);
543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNotDeoptimizationEntry = -1;
545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Generators for the deoptimization entry code.
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class TableEntryGenerator BASE_EMBEDDED {
548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch   public:
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TableEntryGenerator(MacroAssembler* masm, BailoutType type, int count)
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        : masm_(masm), type_(type), count_(count) {}
551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    void Generate();
553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch   protected:
555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    MacroAssembler* masm() const { return masm_; }
556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    BailoutType type() const { return type_; }
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate() const { return masm_->isolate(); }
558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void GeneratePrologue();
560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch   private:
562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int count() const { return count_; }
563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MacroAssembler* masm_;
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Deoptimizer::BailoutType type_;
566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int count_;
567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ConvertJSFrameIndexToFrameIndex(int jsframe_index);
5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static size_t GetMaxDeoptTableSize();
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void EnsureCodeForDeoptimizationEntry(Isolate* isolate,
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               BailoutType type,
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               int max_entry_id);
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return isolate_; }
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMinNumberOfEntries = 64;
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxNumberOfEntries = 16384;
582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
58344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Deoptimizer(Isolate* isolate,
58444f0eee88ff00398ff7f715fab053374d808c90dSteve Block              JSFunction* function,
585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch              BailoutType type,
586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch              unsigned bailout_id,
587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch              Address from,
5883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch              int fp_to_sp_delta,
5893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch              Code* optimized_code);
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* FindOptimizedCode(JSFunction* function, Code* optimized_code);
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PrintFunctionName();
592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DeleteFrameDescriptions();
593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DoComputeOutputFrames();
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DoComputeJSFrame(int frame_index);
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DoComputeInterpretedFrame(int frame_index);
597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DoComputeArgumentsAdaptorFrame(int frame_index);
598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DoComputeConstructStubFrame(int frame_index);
599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DoComputeAccessorStubFrame(int frame_index, bool is_setter_stub_frame);
600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DoComputeCompiledStubFrame(int frame_index);
601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void WriteTranslatedValueToOutput(
603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedFrame::iterator* iterator, int* input_index, int frame_index,
604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      unsigned output_offset, const char* debug_hint_string = nullptr,
605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Address output_address_for_materialization = nullptr);
606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void WriteValueToOutput(Object* value, int input_index, int frame_index,
607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          unsigned output_offset,
608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          const char* debug_hint_string);
609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DebugPrintOutputSlot(intptr_t value, int frame_index,
610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            unsigned output_offset,
611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* debug_hint_string);
612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned ComputeInputFrameSize() const;
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned ComputeJavascriptFixedSize(JSFunction* function) const;
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned ComputeInterpretedFixedSize(JSFunction* function) const;
616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned ComputeIncomingArgumentSize(JSFunction* function) const;
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static unsigned ComputeOutgoingArgumentSize(Code* code, unsigned bailout_id);
619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Object* ComputeLiteral(int index) const;
621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static void GenerateDeoptimizationEntries(
623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      MacroAssembler* masm, int count, BailoutType type);
624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Marks all the code in the given context for deoptimization.
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void MarkAllCodeForContext(Context* native_context);
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit all the known optimized functions in a given context.
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void VisitAllOptimizedFunctionsForContext(
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Context* context, OptimizedFunctionVisitor* visitor);
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Deoptimizes all code marked in the given context.
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void DeoptimizeMarkedCodeForContext(Context* native_context);
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Patch the given code so that it will deoptimize itself.
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void PatchCodeForDeoptimization(Isolate* isolate, Code* code);
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Searches the list of known deoptimizing code for a Code object
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // containing the given address (which is supposedly faster than
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // searching all code objects).
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* FindDeoptimizingCode(Address addr);
642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Fill the input from from a JavaScript frame. This is used when
6443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // the debugger needs to inspect an optimized frame. For normal
6453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // deoptimizations the input frame is filled in generated code.
6463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void FillInputFrame(Address tos, JavaScriptFrame* frame);
6473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fill the given output frame's registers to contain the failure handler
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // address and the number of parameters for a stub failure trampoline.
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetPlatformCompiledStubRegisters(FrameDescription* output_frame,
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        CodeStubDescriptor* desc);
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fill the given output frame's double registers with the original values
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // from the input frame's double registers.
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CopyDoubleRegisters(FrameDescription* output_frame);
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Determines whether the input frame contains alignment padding by looking
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // at the dynamic alignment state slot inside the frame.
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasAlignmentPadding(JSFunction* function);
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
66144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate_;
662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  JSFunction* function_;
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* compiled_code_;
664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned bailout_id_;
665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  BailoutType bailout_type_;
666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address from_;
667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int fp_to_sp_delta_;
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int has_alignment_padding_;
669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Input frame description.
671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FrameDescription* input_;
672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Number of output frames.
673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int output_count_;
6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Number of output js frames.
6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int jsframe_count_;
676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Array of output frame descriptions.
677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FrameDescription** output_;
678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Key for lookup of previously materialized objects
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address stack_fp_;
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedState translated_state_;
683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct ValueToMaterialize {
684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_slot_address_;
685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame::iterator value_;
686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::vector<ValueToMaterialize> values_to_materialize_;
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation* disallow_heap_allocation_;
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeTracer::Scope* trace_scope_;
694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
69569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int table_entry_size_;
696b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
697b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  friend class FrameDescription;
6983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  friend class DeoptimizedFrameInfo;
699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass RegisterValues {
703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t GetRegister(unsigned n) const {
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This convoluted DCHECK is needed to work around a gcc problem that
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // improperly detects an array bounds overflow in optimized debug builds
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // when using a plain DCHECK.
709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (n >= arraysize(registers_)) {
710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(false);
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 0;
712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return registers_[n];
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double GetDoubleRegister(unsigned n) const {
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(n < arraysize(double_registers_));
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return double_registers_[n];
720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetRegister(unsigned n, intptr_t value) {
723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(n < arraysize(registers_));
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    registers_[n] = value;
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetDoubleRegister(unsigned n, double value) {
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(n < arraysize(double_registers_));
729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    double_registers_[n] = value;
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t registers_[Register::kNumRegisters];
733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double double_registers_[DoubleRegister::kMaxNumRegisters];
734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass FrameDescription {
738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FrameDescription(uint32_t frame_size,
740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                   JSFunction* function);
741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void* operator new(size_t size, uint32_t frame_size) {
74344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Subtracts kPointerSize, as the member frame_content_ already supplies
74444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // the first element of the area to store the frame.
74544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return malloc(size + frame_size - kPointerSize);
746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
74869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void operator delete(void* pointer, uint32_t frame_size) {
74969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    free(pointer);
75069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
75169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void operator delete(void* description) {
753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    free(description);
754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  uint32_t GetFrameSize() const {
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(static_cast<uint32_t>(frame_size_) == frame_size_);
7583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return static_cast<uint32_t>(frame_size_);
7593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  JSFunction* GetFunction() const { return function_; }
762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  unsigned GetOffsetFromSlotIndex(int slot_index);
764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
765b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t GetFrameSlot(unsigned offset) {
766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return *GetFrameSlotPointer(offset);
767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address GetFramePointerAddress() {
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int fp_offset = GetFrameSize() -
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    (ComputeParametersCount() + 1) * kPointerSize -
772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    StandardFrameConstants::kCallerSPOffset;
773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return reinterpret_cast<Address>(GetFrameSlotPointer(fp_offset));
774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
775b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RegisterValues* GetRegisterValues() { return &register_values_; }
777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetFrameSlot(unsigned offset, intptr_t value) {
779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    *GetFrameSlotPointer(offset) = value;
780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetCallerPc(unsigned offset, intptr_t value);
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetCallerFp(unsigned offset, intptr_t value);
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetCallerConstantPool(unsigned offset, intptr_t value);
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t GetRegister(unsigned n) const {
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return register_values_.GetRegister(n);
790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  double GetDoubleRegister(unsigned n) const {
793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return register_values_.GetDoubleRegister(n);
794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetRegister(unsigned n, intptr_t value) {
797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    register_values_.SetRegister(n, value);
798b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
799b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetDoubleRegister(unsigned n, double value) {
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    register_values_.SetDoubleRegister(n, value);
802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t GetTop() const { return top_; }
805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetTop(intptr_t top) { top_ = top; }
806b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
807b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t GetPc() const { return pc_; }
808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetPc(intptr_t pc) { pc_ = pc; }
809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
810b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t GetFp() const { return fp_; }
811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetFp(intptr_t fp) { fp_ = fp; }
812b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  intptr_t GetContext() const { return context_; }
8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetContext(intptr_t context) { context_ = context; }
8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t GetConstantPool() const { return constant_pool_; }
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetConstantPool(intptr_t constant_pool) {
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    constant_pool_ = constant_pool;
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Smi* GetState() const { return state_; }
822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetState(Smi* state) { state_ = state; }
823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetContinuation(intptr_t pc) { continuation_ = pc; }
825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StackFrame::Type GetFrameType() const { return type_; }
8273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetFrameType(StackFrame::Type type) { type_ = type; }
8283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Get the incoming arguments count.
8303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int ComputeParametersCount();
8313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Get a parameter value for an unoptimized frame.
8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* GetParameter(int index);
8343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Get the expression stack height for a unoptimized frame.
8363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  unsigned GetExpressionCount();
8373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Get the expression stack value for an unoptimized frame.
8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* GetExpression(int index);
8403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int registers_offset() {
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return OFFSET_OF(FrameDescription, register_values_.registers_);
843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int double_registers_offset() {
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return OFFSET_OF(FrameDescription, register_values_.double_registers_);
847b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
848b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
849b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int frame_size_offset() {
850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return offsetof(FrameDescription, frame_size_);
851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
852b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int pc_offset() { return offsetof(FrameDescription, pc_); }
854b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int state_offset() { return offsetof(FrameDescription, state_); }
856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int continuation_offset() {
858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return offsetof(FrameDescription, continuation_);
859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int frame_content_offset() {
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return offsetof(FrameDescription, frame_content_);
863b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
865b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const uint32_t kZapUint32 = 0xbeeddead;
867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Frame_size_ must hold a uint32_t value.  It is only a uintptr_t to
8693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // keep the variable-size array frame_content_ of type intptr_t at
8703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // the end of the structure aligned.
871b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uintptr_t frame_size_;  // Number of bytes.
872b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  JSFunction* function_;
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RegisterValues register_values_;
874b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t top_;
875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t pc_;
876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t fp_;
8773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  intptr_t context_;
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t constant_pool_;
8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StackFrame::Type type_;
880b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Smi* state_;
881b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Continuation is the PC where the execution continues after
883b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // deoptimizing.
884b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t continuation_;
885b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
88644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // This must be at the end of the object as the object is allocated larger
88744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // than it's definition indicate to extend this array.
88844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  intptr_t frame_content_[1];
88944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  intptr_t* GetFrameSlotPointer(unsigned offset) {
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(offset < frame_size_);
892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return reinterpret_cast<intptr_t*>(
893b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        reinterpret_cast<Address>(this) + frame_content_offset() + offset);
894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ComputeFixedSize();
897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
898b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DeoptimizerData {
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit DeoptimizerData(MemoryAllocator* allocator);
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~DeoptimizerData();
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Iterate(ObjectVisitor* v);
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryAllocator* allocator_;
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int deopt_entry_code_entries_[Deoptimizer::kBailoutTypesWithCodeEntry];
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* deopt_entry_code_[Deoptimizer::kBailoutTypesWithCodeEntry];
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeoptimizedFrameInfo* deoptimized_frame_info_;
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Deoptimizer* current_;
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class Deoptimizer;
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(DeoptimizerData);
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TranslationBuffer BASE_EMBEDDED {
923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { }
925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
926b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int CurrentIndex() const { return contents_.length(); }
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Add(int32_t value, Zone* zone);
928b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<ByteArray> CreateByteArray(Factory* factory);
930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
931b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<uint8_t> contents_;
933b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
934b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
935b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
936b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TranslationIterator BASE_EMBEDDED {
937b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TranslationIterator(ByteArray* buffer, int index)
939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : buffer_(buffer), index_(index) {
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index >= 0 && index < buffer->length());
941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
942b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
943b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t Next();
944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
94569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  bool HasNext() const { return index_ < buffer_->length(); }
946b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Skip(int n) {
948b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    for (int i = 0; i < n; i++) Next();
949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ByteArray* buffer_;
953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int index_;
954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
955b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define TRANSLATION_OPCODE_LIST(V) \
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(BEGIN)                         \
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(JS_FRAME)                      \
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(INTERPRETED_FRAME)             \
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(CONSTRUCT_STUB_FRAME)          \
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(GETTER_STUB_FRAME)             \
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(SETTER_STUB_FRAME)             \
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(ARGUMENTS_ADAPTOR_FRAME)       \
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(COMPILED_STUB_FRAME)           \
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(DUPLICATED_OBJECT)             \
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(ARGUMENTS_OBJECT)              \
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(CAPTURED_OBJECT)               \
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(REGISTER)                      \
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(INT32_REGISTER)                \
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(UINT32_REGISTER)               \
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(BOOL_REGISTER)                 \
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(DOUBLE_REGISTER)               \
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(STACK_SLOT)                    \
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(INT32_STACK_SLOT)              \
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(UINT32_STACK_SLOT)             \
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(BOOL_STACK_SLOT)               \
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(DOUBLE_STACK_SLOT)             \
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(LITERAL)                       \
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(JS_FRAME_FUNCTION)
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass Translation BASE_EMBEDDED {
984b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_TRANSLATION_OPCODE_ENUM(item) item,
986b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  enum Opcode {
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TRANSLATION_OPCODE_LIST(DECLARE_TRANSLATION_OPCODE_ENUM)
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LAST = LITERAL
989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_TRANSLATION_OPCODE_ENUM
991b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count,
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              Zone* zone)
994b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : buffer_(buffer),
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        index_(buffer->CurrentIndex()),
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        zone_(zone) {
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    buffer_->Add(BEGIN, zone);
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    buffer_->Add(frame_count, zone);
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    buffer_->Add(jsframe_count, zone);
1000b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1001b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1002b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int index() const { return index_; }
1003b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1004b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Commands.
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height);
1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void BeginInterpretedFrame(BailoutId bytecode_offset, int literal_id,
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             unsigned height);
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void BeginCompiledStubFrame(int height);
10093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
10103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void BeginConstructStubFrame(int literal_id, unsigned height);
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BeginGetterStubFrame(int literal_id);
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BeginSetterStubFrame(int literal_id);
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BeginArgumentsObject(int args_length);
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BeginCapturedObject(int length);
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void DuplicateObject(int object_index);
1016b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void StoreRegister(Register reg);
1017b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void StoreInt32Register(Register reg);
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void StoreUint32Register(Register reg);
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void StoreBoolRegister(Register reg);
1020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void StoreDoubleRegister(DoubleRegister reg);
1021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void StoreStackSlot(int index);
1022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void StoreInt32StackSlot(int index);
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void StoreUint32StackSlot(int index);
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void StoreBoolStackSlot(int index);
1025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void StoreDoubleStackSlot(int index);
1026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void StoreLiteral(int literal_id);
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void StoreArgumentsObject(bool args_known, int args_index, int args_length);
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void StoreJSFrameFunction();
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return zone_; }
1031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int NumberOfOperandsFor(Opcode opcode);
1033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
10343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
1035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const char* StringFor(Opcode opcode);
1036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
1037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
1039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TranslationBuffer* buffer_;
1040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int index_;
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
1042b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1043b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MaterializedObjectStore {
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit MaterializedObjectStore(Isolate* isolate) : isolate_(isolate) {
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArray> Get(Address fp);
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Set(Address fp, Handle<FixedArray> materialized_objects);
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool Remove(Address fp);
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() { return isolate_; }
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArray> GetStackEntries();
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArray> EnsureStackEntries(int size);
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int StackIdToIndex(Address fp);
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate_;
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  List<Address> frame_fps_;
10638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch};
10648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
10658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
10663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Class used to represent an unoptimized frame when the debugger
10673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// needs to inspect a frame that is part of an optimized frame. The
10683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// internally used FrameDescription objects are not GC safe so for use
10693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// by the debugger frame information is copied to an object of this type.
10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Represents parameters in unadapted form so their number might mismatch
10713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// formal parameter count.
10723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass DeoptimizedFrameInfo : public Malloced {
10733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
10743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
10753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       int frame_index,
10763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       bool has_arguments_adaptor,
10773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       bool has_construct_stub);
10783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  virtual ~DeoptimizedFrameInfo();
10793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // GC support.
10813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void Iterate(ObjectVisitor* v);
10823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Return the number of incoming arguments.
10843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int parameters_count() { return parameters_count_; }
10853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Return the height of the expression stack.
10873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int expression_count() { return expression_count_; }
10883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Get the frame function.
10903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  JSFunction* GetFunction() {
10913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return function_;
10923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
10933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get the frame context.
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* GetContext() { return context_; }
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if this frame is preceded by construct stub frame.  The bottom-most
10983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // inlined frame might still be called by an uninlined construct stub.
10993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool HasConstructStub() {
11003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return has_construct_stub_;
11013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
11023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Get an incoming argument.
11043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Object* GetParameter(int index) {
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(0 <= index && index < parameters_count());
11063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return parameters_[index];
11073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
11083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Get an expression from the expression stack.
11103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Object* GetExpression(int index) {
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(0 <= index && index < expression_count());
11123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return expression_stack_[index];
11133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
11143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int GetSourcePosition() {
11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return source_position_;
11173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
11183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
11203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Set an incoming argument.
11213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void SetParameter(int index, Object* obj) {
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(0 <= index && index < parameters_count());
11233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    parameters_[index] = obj;
11243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
11253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Set an expression on the expression stack.
11273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void SetExpression(int index, Object* obj) {
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(0 <= index && index < expression_count());
11293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    expression_stack_[index] = obj;
11303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
11313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  JSFunction* function_;
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context_;
11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool has_construct_stub_;
11353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int parameters_count_;
11363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int expression_count_;
11373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Object** parameters_;
11383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Object** expression_stack_;
11393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int source_position_;
11403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  friend class Deoptimizer;
11423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
11433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
1146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif  // V8_DEOPTIMIZER_H_
1148