Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/deoptimizer.h b/src/deoptimizer.h
index 612d5f6..10685b6 100644
--- a/src/deoptimizer.h
+++ b/src/deoptimizer.h
@@ -5,70 +5,292 @@
 #ifndef V8_DEOPTIMIZER_H_
 #define V8_DEOPTIMIZER_H_
 
-#include "src/v8.h"
-
 #include "src/allocation.h"
 #include "src/macro-assembler.h"
-#include "src/zone-inl.h"
 
 
 namespace v8 {
 namespace internal {
 
-
-static inline double read_double_value(Address p) {
-  double d;
-  memcpy(&d, p, sizeof(d));
-  return d;
-}
-
-
 class FrameDescription;
 class TranslationIterator;
 class DeoptimizedFrameInfo;
+class TranslatedState;
+class RegisterValues;
 
-template<typename T>
-class HeapNumberMaterializationDescriptor BASE_EMBEDDED {
+class TranslatedValue {
  public:
-  HeapNumberMaterializationDescriptor(T destination, double value)
-      : destination_(destination), value_(value) { }
+  // Allocation-less getter of the value.
+  // Returns heap()->arguments_marker() if allocation would be
+  // necessary to get the value.
+  Object* GetRawValue() const;
+  Handle<Object> GetValue();
 
-  T destination() const { return destination_; }
-  double value() const { return value_; }
+  bool IsMaterializedObject() const;
 
  private:
-  T destination_;
-  double value_;
+  friend class TranslatedState;
+  friend class TranslatedFrame;
+
+  enum Kind {
+    kInvalid,
+    kTagged,
+    kInt32,
+    kUInt32,
+    kBoolBit,
+    kDouble,
+    kCapturedObject,    // Object captured by the escape analysis.
+                        // The number of nested objects can be obtained
+                        // with the DeferredObjectLength() method
+                        // (the values of the nested objects follow
+                        // this value in the depth-first order.)
+    kDuplicatedObject,  // Duplicated object of a deferred object.
+    kArgumentsObject    // Arguments object - only used to keep indexing
+                        // in sync, it should not be materialized.
+  };
+
+  TranslatedValue(TranslatedState* container, Kind kind)
+      : kind_(kind), container_(container) {}
+  Kind kind() const { return kind_; }
+  void Handlify();
+  int GetChildrenCount() const;
+
+  static TranslatedValue NewArgumentsObject(TranslatedState* container,
+                                            int length, int object_index);
+  static TranslatedValue NewDeferredObject(TranslatedState* container,
+                                           int length, int object_index);
+  static TranslatedValue NewDuplicateObject(TranslatedState* container, int id);
+  static TranslatedValue NewDouble(TranslatedState* container, double value);
+  static TranslatedValue NewInt32(TranslatedState* container, int32_t value);
+  static TranslatedValue NewUInt32(TranslatedState* container, uint32_t value);
+  static TranslatedValue NewBool(TranslatedState* container, uint32_t value);
+  static TranslatedValue NewTagged(TranslatedState* container, Object* literal);
+  static TranslatedValue NewInvalid(TranslatedState* container);
+
+  Isolate* isolate() const;
+  void MaterializeSimple();
+
+  Kind kind_;
+  TranslatedState* container_;  // This is only needed for materialization of
+                                // objects and constructing handles (to get
+                                // to the isolate).
+
+  MaybeHandle<Object> value_;  // Before handlification, this is always null,
+                               // after materialization it is never null,
+                               // in between it is only null if the value needs
+                               // to be materialized.
+
+  struct MaterializedObjectInfo {
+    int id_;
+    int length_;  // Applies only to kArgumentsObject or kCapturedObject kinds.
+  };
+
+  union {
+    // kind kTagged. After handlification it is always nullptr.
+    Object* raw_literal_;
+    // kind is kUInt32 or kBoolBit.
+    uint32_t uint32_value_;
+    // kind is kInt32.
+    int32_t int32_value_;
+    // kind is kDouble
+    double double_value_;
+    // kind is kDuplicatedObject or kArgumentsObject or kCapturedObject.
+    MaterializedObjectInfo materialization_info_;
+  };
+
+  // Checked accessors for the union members.
+  Object* raw_literal() const;
+  int32_t int32_value() const;
+  uint32_t uint32_value() const;
+  double double_value() const;
+  int object_length() const;
+  int object_index() const;
 };
 
 
-class ObjectMaterializationDescriptor BASE_EMBEDDED {
+class TranslatedFrame {
  public:
-  ObjectMaterializationDescriptor(
-      Address slot_address, int frame, int length, int duplicate, bool is_args)
-      : slot_address_(slot_address),
-        jsframe_index_(frame),
-        object_length_(length),
-        duplicate_object_(duplicate),
-        is_arguments_(is_args) { }
+  enum Kind {
+    kFunction,
+    kInterpretedFunction,
+    kGetter,
+    kSetter,
+    kArgumentsAdaptor,
+    kConstructStub,
+    kCompiledStub,
+    kInvalid
+  };
 
-  Address slot_address() const { return slot_address_; }
-  int jsframe_index() const { return jsframe_index_; }
-  int object_length() const { return object_length_; }
-  int duplicate_object() const { return duplicate_object_; }
-  bool is_arguments() const { return is_arguments_; }
+  int GetValueCount();
 
-  // Only used for allocated receivers in DoComputeConstructStubFrame.
-  void patch_slot_address(intptr_t slot) {
-    slot_address_ = reinterpret_cast<Address>(slot);
-  }
+  Kind kind() const { return kind_; }
+  BailoutId node_id() const { return node_id_; }
+  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
+  int height() const { return height_; }
+
+  class iterator {
+   public:
+    iterator& operator++() {
+      AdvanceIterator(&position_);
+      return *this;
+    }
+
+    iterator operator++(int) {
+      iterator original(position_);
+      AdvanceIterator(&position_);
+      return original;
+    }
+
+    bool operator==(const iterator& other) const {
+      return position_ == other.position_;
+    }
+    bool operator!=(const iterator& other) const { return !(*this == other); }
+
+    TranslatedValue& operator*() { return (*position_); }
+    TranslatedValue* operator->() { return &(*position_); }
+
+   private:
+    friend TranslatedFrame;
+
+    explicit iterator(std::deque<TranslatedValue>::iterator position)
+        : position_(position) {}
+
+    std::deque<TranslatedValue>::iterator position_;
+  };
+
+  typedef TranslatedValue& reference;
+  typedef TranslatedValue const& const_reference;
+
+  iterator begin() { return iterator(values_.begin()); }
+  iterator end() { return iterator(values_.end()); }
+
+  reference front() { return values_.front(); }
+  const_reference front() const { return values_.front(); }
 
  private:
-  Address slot_address_;
-  int jsframe_index_;
-  int object_length_;
-  int duplicate_object_;
-  bool is_arguments_;
+  friend class TranslatedState;
+
+  // Constructor static methods.
+  static TranslatedFrame JSFrame(BailoutId node_id,
+                                 SharedFunctionInfo* shared_info, int height);
+  static TranslatedFrame InterpretedFrame(BailoutId bytecode_offset,
+                                          SharedFunctionInfo* shared_info,
+                                          int height);
+  static TranslatedFrame AccessorFrame(Kind kind,
+                                       SharedFunctionInfo* shared_info);
+  static TranslatedFrame ArgumentsAdaptorFrame(SharedFunctionInfo* shared_info,
+                                               int height);
+  static TranslatedFrame ConstructStubFrame(SharedFunctionInfo* shared_info,
+                                            int height);
+  static TranslatedFrame CompiledStubFrame(int height, Isolate* isolate) {
+    return TranslatedFrame(kCompiledStub, isolate, nullptr, height);
+  }
+  static TranslatedFrame InvalidFrame() {
+    return TranslatedFrame(kInvalid, nullptr);
+  }
+
+  static void AdvanceIterator(std::deque<TranslatedValue>::iterator* iter);
+
+  TranslatedFrame(Kind kind, Isolate* isolate,
+                  SharedFunctionInfo* shared_info = nullptr, int height = 0)
+      : kind_(kind),
+        node_id_(BailoutId::None()),
+        raw_shared_info_(shared_info),
+        height_(height),
+        isolate_(isolate) {}
+
+
+  void Add(const TranslatedValue& value) { values_.push_back(value); }
+  void Handlify();
+
+  Kind kind_;
+  BailoutId node_id_;
+  SharedFunctionInfo* raw_shared_info_;
+  Handle<SharedFunctionInfo> shared_info_;
+  int height_;
+  Isolate* isolate_;
+
+  typedef std::deque<TranslatedValue> ValuesContainer;
+
+  ValuesContainer values_;
+};
+
+
+// Auxiliary class for translating deoptimization values.
+// Typical usage sequence:
+//
+// 1. Construct the instance. This will involve reading out the translations
+//    and resolving them to values using the supplied frame pointer and
+//    machine state (registers). This phase is guaranteed not to allocate
+//    and not to use any HandleScope. Any object pointers will be stored raw.
+//
+// 2. Handlify pointers. This will convert all the raw pointers to handles.
+//
+// 3. Reading out the frame values.
+//
+// Note: After the instance is constructed, it is possible to iterate over
+// the values eagerly.
+
+class TranslatedState {
+ public:
+  TranslatedState();
+  explicit TranslatedState(JavaScriptFrame* frame);
+
+  void Prepare(bool has_adapted_arguments, Address stack_frame_pointer);
+
+  // Store newly materialized values into the isolate.
+  void StoreMaterializedValuesAndDeopt();
+
+  typedef std::vector<TranslatedFrame>::iterator iterator;
+  iterator begin() { return frames_.begin(); }
+  iterator end() { return frames_.end(); }
+
+  typedef std::vector<TranslatedFrame>::const_iterator const_iterator;
+  const_iterator begin() const { return frames_.begin(); }
+  const_iterator end() const { return frames_.end(); }
+
+  std::vector<TranslatedFrame>& frames() { return frames_; }
+
+  TranslatedFrame* GetArgumentsInfoFromJSFrameIndex(int jsframe_index,
+                                                    int* arguments_count);
+
+  Isolate* isolate() { return isolate_; }
+
+  void Init(Address input_frame_pointer, TranslationIterator* iterator,
+            FixedArray* literal_array, RegisterValues* registers,
+            FILE* trace_file);
+
+ private:
+  friend TranslatedValue;
+
+  TranslatedFrame CreateNextTranslatedFrame(TranslationIterator* iterator,
+                                            FixedArray* literal_array,
+                                            Address fp,
+                                            FILE* trace_file);
+  TranslatedValue CreateNextTranslatedValue(int frame_index, int value_index,
+                                            TranslationIterator* iterator,
+                                            FixedArray* literal_array,
+                                            Address fp,
+                                            RegisterValues* registers,
+                                            FILE* trace_file);
+
+  void UpdateFromPreviouslyMaterializedObjects();
+  Handle<Object> MaterializeAt(int frame_index, int* value_index);
+  Handle<Object> MaterializeObjectAt(int object_index);
+  bool GetAdaptedArguments(Handle<JSObject>* result, int frame_index);
+
+  static uint32_t GetUInt32Slot(Address fp, int slot_index);
+
+  std::vector<TranslatedFrame> frames_;
+  Isolate* isolate_;
+  Address stack_frame_pointer_;
+  bool has_adapted_arguments_;
+
+  struct ObjectPosition {
+    int frame_index_;
+    int value_index_;
+  };
+  std::deque<ObjectPosition> object_positions_;
 };
 
 
@@ -88,6 +310,87 @@
 };
 
 
+#define DEOPT_MESSAGES_LIST(V)                                                 \
+  V(kAccessCheck, "Access check needed")                                       \
+  V(kNoReason, "no reason")                                                    \
+  V(kConstantGlobalVariableAssignment, "Constant global variable assignment")  \
+  V(kConversionOverflow, "conversion overflow")                                \
+  V(kDivisionByZero, "division by zero")                                       \
+  V(kElementsKindUnhandledInKeyedLoadGenericStub,                              \
+    "ElementsKind unhandled in KeyedLoadGenericStub")                          \
+  V(kExpectedHeapNumber, "Expected heap number")                               \
+  V(kExpectedSmi, "Expected smi")                                              \
+  V(kForcedDeoptToRuntime, "Forced deopt to runtime")                          \
+  V(kHole, "hole")                                                             \
+  V(kHoleyArrayDespitePackedElements_kindFeedback,                             \
+    "Holey array despite packed elements_kind feedback")                       \
+  V(kInstanceMigrationFailed, "instance migration failed")                     \
+  V(kInsufficientTypeFeedbackForCallWithArguments,                             \
+    "Insufficient type feedback for call with arguments")                      \
+  V(kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation,                 \
+    "Insufficient type feedback for combined type of binary operation")        \
+  V(kInsufficientTypeFeedbackForGenericNamedAccess,                            \
+    "Insufficient type feedback for generic named access")                     \
+  V(kInsufficientTypeFeedbackForKeyedLoad,                                     \
+    "Insufficient type feedback for keyed load")                               \
+  V(kInsufficientTypeFeedbackForKeyedStore,                                    \
+    "Insufficient type feedback for keyed store")                              \
+  V(kInsufficientTypeFeedbackForLHSOfBinaryOperation,                          \
+    "Insufficient type feedback for LHS of binary operation")                  \
+  V(kInsufficientTypeFeedbackForRHSOfBinaryOperation,                          \
+    "Insufficient type feedback for RHS of binary operation")                  \
+  V(kKeyIsNegative, "key is negative")                                         \
+  V(kLiteralsWereDisposed, "literals have been disposed")                      \
+  V(kLostPrecision, "lost precision")                                          \
+  V(kLostPrecisionOrNaN, "lost precision or NaN")                              \
+  V(kMementoFound, "memento found")                                            \
+  V(kMinusZero, "minus zero")                                                  \
+  V(kNaN, "NaN")                                                               \
+  V(kNegativeKeyEncountered, "Negative key encountered")                       \
+  V(kNegativeValue, "negative value")                                          \
+  V(kNoCache, "no cache")                                                      \
+  V(kNonStrictElementsInKeyedLoadGenericStub,                                  \
+    "non-strict elements in KeyedLoadGenericStub")                             \
+  V(kNotADateObject, "not a date object")                                      \
+  V(kNotAHeapNumber, "not a heap number")                                      \
+  V(kNotAHeapNumberUndefinedBoolean, "not a heap number/undefined/true/false") \
+  V(kNotAHeapNumberUndefined, "not a heap number/undefined")                   \
+  V(kNotAJavaScriptObject, "not a JavaScript object")                          \
+  V(kNotASmi, "not a Smi")                                                     \
+  V(kNull, "null")                                                             \
+  V(kOutOfBounds, "out of bounds")                                             \
+  V(kOutsideOfRange, "Outside of range")                                       \
+  V(kOverflow, "overflow")                                                     \
+  V(kProxy, "proxy")                                                           \
+  V(kReceiverWasAGlobalObject, "receiver was a global object")                 \
+  V(kSmi, "Smi")                                                               \
+  V(kTooManyArguments, "too many arguments")                                   \
+  V(kTooManyUndetectableTypes, "Too many undetectable types")                  \
+  V(kTracingElementsTransitions, "Tracing elements transitions")               \
+  V(kTypeMismatchBetweenFeedbackAndConstant,                                   \
+    "Type mismatch between feedback and constant")                             \
+  V(kUndefined, "undefined")                                                   \
+  V(kUnexpectedCellContentsInConstantGlobalStore,                              \
+    "Unexpected cell contents in constant global store")                       \
+  V(kUnexpectedCellContentsInGlobalStore,                                      \
+    "Unexpected cell contents in global store")                                \
+  V(kUnexpectedObject, "unexpected object")                                    \
+  V(kUnexpectedRHSOfBinaryOperation, "Unexpected RHS of binary operation")     \
+  V(kUninitializedBoilerplateInFastClone,                                      \
+    "Uninitialized boilerplate in fast clone")                                 \
+  V(kUninitializedBoilerplateLiterals, "Uninitialized boilerplate literals")   \
+  V(kUnknownMapInPolymorphicAccess, "Unknown map in polymorphic access")       \
+  V(kUnknownMapInPolymorphicCall, "Unknown map in polymorphic call")           \
+  V(kUnknownMapInPolymorphicElementAccess,                                     \
+    "Unknown map in polymorphic element access")                               \
+  V(kUnknownMap, "Unknown map")                                                \
+  V(kValueMismatch, "value mismatch")                                          \
+  V(kWrongInstanceType, "wrong instance type")                                 \
+  V(kWrongMap, "wrong map")                                                    \
+  V(kUndefinedOrNullInForIn, "null or undefined in for-in")                    \
+  V(kUndefinedOrNullInToObject, "null or undefined in ToObject")
+
+
 class Deoptimizer : public Malloced {
  public:
   enum BailoutType {
@@ -96,46 +399,46 @@
     SOFT,
     // This last bailout type is not really a bailout, but used by the
     // debugger to deoptimize stack frames to allow inspection.
-    DEBUGGER
+    DEBUGGER,
+    kBailoutTypesWithCodeEntry = SOFT + 1
   };
 
-  static const int kBailoutTypesWithCodeEntry = SOFT + 1;
+#define DEOPT_MESSAGES_CONSTANTS(C, T) C,
+  enum DeoptReason {
+    DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_CONSTANTS) kLastDeoptReason
+  };
+#undef DEOPT_MESSAGES_CONSTANTS
+  static const char* GetDeoptReason(DeoptReason deopt_reason);
 
-  struct Reason {
-    Reason(int r, const char* m, const char* d)
-        : raw_position(r), mnemonic(m), detail(d) {}
+  struct DeoptInfo {
+    DeoptInfo(SourcePosition position, const char* m, DeoptReason d)
+        : position(position), mnemonic(m), deopt_reason(d), inlining_id(0) {}
 
-    bool operator==(const Reason& other) const {
-      return raw_position == other.raw_position &&
-             CStringEquals(mnemonic, other.mnemonic) &&
-             CStringEquals(detail, other.detail);
-    }
-
-    bool operator!=(const Reason& other) const { return !(*this == other); }
-
-    int raw_position;
+    SourcePosition position;
     const char* mnemonic;
-    const char* detail;
+    DeoptReason deopt_reason;
+    int inlining_id;
   };
 
+  static DeoptInfo GetDeoptInfo(Code* code, byte* from);
+
   struct JumpTableEntry : public ZoneObject {
-    inline JumpTableEntry(Address entry, const Reason& the_reason,
+    inline JumpTableEntry(Address entry, const DeoptInfo& deopt_info,
                           Deoptimizer::BailoutType type, bool frame)
         : label(),
           address(entry),
-          reason(the_reason),
+          deopt_info(deopt_info),
           bailout_type(type),
           needs_frame(frame) {}
 
     bool IsEquivalentTo(const JumpTableEntry& other) const {
       return address == other.address && bailout_type == other.bailout_type &&
-             needs_frame == other.needs_frame &&
-             (!FLAG_trace_deopt || reason == other.reason);
+             needs_frame == other.needs_frame;
     }
 
     Label label;
     Address address;
-    Reason reason;
+    DeoptInfo deopt_info;
     Deoptimizer::BailoutType bailout_type;
     bool needs_frame;
   };
@@ -184,9 +487,6 @@
   // Deoptimize all code in the given isolate.
   static void DeoptimizeAll(Isolate* isolate);
 
-  // Deoptimize code associated with the given global object.
-  static void DeoptimizeGlobalObject(JSObject* object);
-
   // Deoptimizes all optimized code that has been previously marked
   // (via code->set_marked_for_deoptimization) and unlinks all functions that
   // refer to that code.
@@ -204,10 +504,7 @@
   void MaterializeHeapObjects(JavaScriptFrameIterator* it);
 
   void MaterializeHeapNumbersForDebuggerInspectableFrame(
-      Address parameters_top,
-      uint32_t parameters_size,
-      Address expressions_top,
-      uint32_t expressions_size,
+      int frame_index, int parameter_count, int expression_count,
       DeoptimizedFrameInfo* info);
 
   static void ComputeOutputFrames(Deoptimizer* deoptimizer);
@@ -247,11 +544,10 @@
   static const int kNotDeoptimizationEntry = -1;
 
   // Generators for the deoptimization entry code.
-  class EntryGenerator BASE_EMBEDDED {
+  class TableEntryGenerator BASE_EMBEDDED {
    public:
-    EntryGenerator(MacroAssembler* masm, BailoutType type)
-        : masm_(masm), type_(type) { }
-    virtual ~EntryGenerator() { }
+    TableEntryGenerator(MacroAssembler* masm, BailoutType type, int count)
+        : masm_(masm), type_(type), count_(count) {}
 
     void Generate();
 
@@ -260,24 +556,13 @@
     BailoutType type() const { return type_; }
     Isolate* isolate() const { return masm_->isolate(); }
 
-    virtual void GeneratePrologue() { }
-
-   private:
-    MacroAssembler* masm_;
-    Deoptimizer::BailoutType type_;
-  };
-
-  class TableEntryGenerator : public EntryGenerator {
-   public:
-    TableEntryGenerator(MacroAssembler* masm, BailoutType type,  int count)
-        : EntryGenerator(masm, type), count_(count) { }
-
-   protected:
-    virtual void GeneratePrologue();
+    void GeneratePrologue();
 
    private:
     int count() const { return count_; }
 
+    MacroAssembler* masm_;
+    Deoptimizer::BailoutType type_;
     int count_;
   };
 
@@ -307,62 +592,33 @@
   void DeleteFrameDescriptions();
 
   void DoComputeOutputFrames();
-  void DoComputeJSFrame(TranslationIterator* iterator, int frame_index);
-  void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
-                                      int frame_index);
-  void DoComputeConstructStubFrame(TranslationIterator* iterator,
-                                   int frame_index);
-  void DoComputeAccessorStubFrame(TranslationIterator* iterator,
-                                  int frame_index,
-                                  bool is_setter_stub_frame);
-  void DoComputeCompiledStubFrame(TranslationIterator* iterator,
-                                  int frame_index);
+  void DoComputeJSFrame(int frame_index);
+  void DoComputeInterpretedFrame(int frame_index);
+  void DoComputeArgumentsAdaptorFrame(int frame_index);
+  void DoComputeConstructStubFrame(int frame_index);
+  void DoComputeAccessorStubFrame(int frame_index, bool is_setter_stub_frame);
+  void DoComputeCompiledStubFrame(int frame_index);
 
-  // Translate object, store the result into an auxiliary array
-  // (deferred_objects_tagged_values_).
-  void DoTranslateObject(TranslationIterator* iterator,
-                         int object_index,
-                         int field_index);
-
-  // Translate value, store the result into the given frame slot.
-  void DoTranslateCommand(TranslationIterator* iterator,
-                          int frame_index,
-                          unsigned output_offset);
-
-  // Translate object, do not store the result anywhere (but do update
-  // the deferred materialization array).
-  void DoTranslateObjectAndSkip(TranslationIterator* iterator);
+  void WriteTranslatedValueToOutput(
+      TranslatedFrame::iterator* iterator, int* input_index, int frame_index,
+      unsigned output_offset, const char* debug_hint_string = nullptr,
+      Address output_address_for_materialization = nullptr);
+  void WriteValueToOutput(Object* value, int input_index, int frame_index,
+                          unsigned output_offset,
+                          const char* debug_hint_string);
+  void DebugPrintOutputSlot(intptr_t value, int frame_index,
+                            unsigned output_offset,
+                            const char* debug_hint_string);
 
   unsigned ComputeInputFrameSize() const;
-  unsigned ComputeFixedSize(JSFunction* function) const;
+  unsigned ComputeJavascriptFixedSize(JSFunction* function) const;
+  unsigned ComputeInterpretedFixedSize(JSFunction* function) const;
 
   unsigned ComputeIncomingArgumentSize(JSFunction* function) const;
-  unsigned ComputeOutgoingArgumentSize() const;
+  static unsigned ComputeOutgoingArgumentSize(Code* code, unsigned bailout_id);
 
   Object* ComputeLiteral(int index) const;
 
-  void AddObjectStart(intptr_t slot_address, int argc, bool is_arguments);
-  void AddObjectDuplication(intptr_t slot, int object_index);
-  void AddObjectTaggedValue(intptr_t value);
-  void AddObjectDoubleValue(double value);
-  void AddDoubleValue(intptr_t slot_address, double value);
-
-  bool ArgumentsObjectIsAdapted(int object_index) {
-    ObjectMaterializationDescriptor desc = deferred_objects_.at(object_index);
-    int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
-    return jsframe_has_adapted_arguments_[reverse_jsframe_index];
-  }
-
-  Handle<JSFunction> ArgumentsObjectFunction(int object_index) {
-    ObjectMaterializationDescriptor desc = deferred_objects_.at(object_index);
-    int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
-    return jsframe_functions_[reverse_jsframe_index];
-  }
-
-  // Helper function for heap object materialization.
-  Handle<Object> MaterializeNextHeapObject();
-  Handle<Object> MaterializeNextValue();
-
   static void GenerateDeoptimizationEntries(
       MacroAssembler* masm, int count, BailoutType type);
 
@@ -420,27 +676,15 @@
   // Array of output frame descriptions.
   FrameDescription** output_;
 
-  // Deferred values to be materialized.
-  List<Object*> deferred_objects_tagged_values_;
-  List<HeapNumberMaterializationDescriptor<int> >
-      deferred_objects_double_values_;
-  List<ObjectMaterializationDescriptor> deferred_objects_;
-  List<HeapNumberMaterializationDescriptor<Address> > deferred_heap_numbers_;
-
   // Key for lookup of previously materialized objects
   Address stack_fp_;
-  Handle<FixedArray> previously_materialized_objects_;
-  int prev_materialized_count_;
 
-  // Output frame information. Only used during heap object materialization.
-  List<Handle<JSFunction> > jsframe_functions_;
-  List<bool> jsframe_has_adapted_arguments_;
-
-  // Materialized objects. Only used during heap object materialization.
-  List<Handle<Object> >* materialized_values_;
-  List<Handle<Object> >* materialized_objects_;
-  int materialization_value_index_;
-  int materialization_object_index_;
+  TranslatedState translated_state_;
+  struct ValueToMaterialize {
+    Address output_slot_address_;
+    TranslatedFrame::iterator value_;
+  };
+  std::vector<ValueToMaterialize> values_to_materialize_;
 
 #ifdef DEBUG
   DisallowHeapAllocation* disallow_heap_allocation_;
@@ -455,6 +699,41 @@
 };
 
 
+class RegisterValues {
+ public:
+  intptr_t GetRegister(unsigned n) const {
+#if DEBUG
+    // This convoluted DCHECK is needed to work around a gcc problem that
+    // improperly detects an array bounds overflow in optimized debug builds
+    // when using a plain DCHECK.
+    if (n >= arraysize(registers_)) {
+      DCHECK(false);
+      return 0;
+    }
+#endif
+    return registers_[n];
+  }
+
+  double GetDoubleRegister(unsigned n) const {
+    DCHECK(n < arraysize(double_registers_));
+    return double_registers_[n];
+  }
+
+  void SetRegister(unsigned n, intptr_t value) {
+    DCHECK(n < arraysize(registers_));
+    registers_[n] = value;
+  }
+
+  void SetDoubleRegister(unsigned n, double value) {
+    DCHECK(n < arraysize(double_registers_));
+    double_registers_[n] = value;
+  }
+
+  intptr_t registers_[Register::kNumRegisters];
+  double double_registers_[DoubleRegister::kMaxNumRegisters];
+};
+
+
 class FrameDescription {
  public:
   FrameDescription(uint32_t frame_size,
@@ -487,11 +766,15 @@
     return *GetFrameSlotPointer(offset);
   }
 
-  double GetDoubleFrameSlot(unsigned offset) {
-    intptr_t* ptr = GetFrameSlotPointer(offset);
-    return read_double_value(reinterpret_cast<Address>(ptr));
+  Address GetFramePointerAddress() {
+    int fp_offset = GetFrameSize() -
+                    (ComputeParametersCount() + 1) * kPointerSize -
+                    StandardFrameConstants::kCallerSPOffset;
+    return reinterpret_cast<Address>(GetFrameSlotPointer(fp_offset));
   }
 
+  RegisterValues* GetRegisterValues() { return &register_values_; }
+
   void SetFrameSlot(unsigned offset, intptr_t value) {
     *GetFrameSlotPointer(offset) = value;
   }
@@ -503,31 +786,19 @@
   void SetCallerConstantPool(unsigned offset, intptr_t value);
 
   intptr_t GetRegister(unsigned n) const {
-#if DEBUG
-    // This convoluted DCHECK is needed to work around a gcc problem that
-    // improperly detects an array bounds overflow in optimized debug builds
-    // when using a plain DCHECK.
-    if (n >= arraysize(registers_)) {
-      DCHECK(false);
-      return 0;
-    }
-#endif
-    return registers_[n];
+    return register_values_.GetRegister(n);
   }
 
   double GetDoubleRegister(unsigned n) const {
-    DCHECK(n < arraysize(double_registers_));
-    return double_registers_[n];
+    return register_values_.GetDoubleRegister(n);
   }
 
   void SetRegister(unsigned n, intptr_t value) {
-    DCHECK(n < arraysize(registers_));
-    registers_[n] = value;
+    register_values_.SetRegister(n, value);
   }
 
   void SetDoubleRegister(unsigned n, double value) {
-    DCHECK(n < arraysize(double_registers_));
-    double_registers_[n] = value;
+    register_values_.SetDoubleRegister(n, value);
   }
 
   intptr_t GetTop() const { return top_; }
@@ -568,31 +839,27 @@
   Object* GetExpression(int index);
 
   static int registers_offset() {
-    return OFFSET_OF(FrameDescription, registers_);
+    return OFFSET_OF(FrameDescription, register_values_.registers_);
   }
 
   static int double_registers_offset() {
-    return OFFSET_OF(FrameDescription, double_registers_);
+    return OFFSET_OF(FrameDescription, register_values_.double_registers_);
   }
 
   static int frame_size_offset() {
-    return OFFSET_OF(FrameDescription, frame_size_);
+    return offsetof(FrameDescription, frame_size_);
   }
 
-  static int pc_offset() {
-    return OFFSET_OF(FrameDescription, pc_);
-  }
+  static int pc_offset() { return offsetof(FrameDescription, pc_); }
 
-  static int state_offset() {
-    return OFFSET_OF(FrameDescription, state_);
-  }
+  static int state_offset() { return offsetof(FrameDescription, state_); }
 
   static int continuation_offset() {
-    return OFFSET_OF(FrameDescription, continuation_);
+    return offsetof(FrameDescription, continuation_);
   }
 
   static int frame_content_offset() {
-    return OFFSET_OF(FrameDescription, frame_content_);
+    return offsetof(FrameDescription, frame_content_);
   }
 
  private:
@@ -603,8 +870,7 @@
   // the end of the structure aligned.
   uintptr_t frame_size_;  // Number of bytes.
   JSFunction* function_;
-  intptr_t registers_[Register::kNumRegisters];
-  double double_registers_[DoubleRegister::kMaxNumRegisters];
+  RegisterValues register_values_;
   intptr_t top_;
   intptr_t pc_;
   intptr_t fp_;
@@ -688,26 +954,30 @@
 };
 
 
-#define TRANSLATION_OPCODE_LIST(V)                                             \
-  V(BEGIN)                                                                     \
-  V(JS_FRAME)                                                                  \
-  V(CONSTRUCT_STUB_FRAME)                                                      \
-  V(GETTER_STUB_FRAME)                                                         \
-  V(SETTER_STUB_FRAME)                                                         \
-  V(ARGUMENTS_ADAPTOR_FRAME)                                                   \
-  V(COMPILED_STUB_FRAME)                                                       \
-  V(DUPLICATED_OBJECT)                                                         \
-  V(ARGUMENTS_OBJECT)                                                          \
-  V(CAPTURED_OBJECT)                                                           \
-  V(REGISTER)                                                                  \
-  V(INT32_REGISTER)                                                            \
-  V(UINT32_REGISTER)                                                           \
-  V(DOUBLE_REGISTER)                                                           \
-  V(STACK_SLOT)                                                                \
-  V(INT32_STACK_SLOT)                                                          \
-  V(UINT32_STACK_SLOT)                                                         \
-  V(DOUBLE_STACK_SLOT)                                                         \
-  V(LITERAL)
+#define TRANSLATION_OPCODE_LIST(V) \
+  V(BEGIN)                         \
+  V(JS_FRAME)                      \
+  V(INTERPRETED_FRAME)             \
+  V(CONSTRUCT_STUB_FRAME)          \
+  V(GETTER_STUB_FRAME)             \
+  V(SETTER_STUB_FRAME)             \
+  V(ARGUMENTS_ADAPTOR_FRAME)       \
+  V(COMPILED_STUB_FRAME)           \
+  V(DUPLICATED_OBJECT)             \
+  V(ARGUMENTS_OBJECT)              \
+  V(CAPTURED_OBJECT)               \
+  V(REGISTER)                      \
+  V(INT32_REGISTER)                \
+  V(UINT32_REGISTER)               \
+  V(BOOL_REGISTER)                 \
+  V(DOUBLE_REGISTER)               \
+  V(STACK_SLOT)                    \
+  V(INT32_STACK_SLOT)              \
+  V(UINT32_STACK_SLOT)             \
+  V(BOOL_STACK_SLOT)               \
+  V(DOUBLE_STACK_SLOT)             \
+  V(LITERAL)                       \
+  V(JS_FRAME_FUNCTION)
 
 
 class Translation BASE_EMBEDDED {
@@ -733,7 +1003,9 @@
 
   // Commands.
   void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height);
-  void BeginCompiledStubFrame();
+  void BeginInterpretedFrame(BailoutId bytecode_offset, int literal_id,
+                             unsigned height);
+  void BeginCompiledStubFrame(int height);
   void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
   void BeginConstructStubFrame(int literal_id, unsigned height);
   void BeginGetterStubFrame(int literal_id);
@@ -744,13 +1016,16 @@
   void StoreRegister(Register reg);
   void StoreInt32Register(Register reg);
   void StoreUint32Register(Register reg);
+  void StoreBoolRegister(Register reg);
   void StoreDoubleRegister(DoubleRegister reg);
   void StoreStackSlot(int index);
   void StoreInt32StackSlot(int index);
   void StoreUint32StackSlot(int index);
+  void StoreBoolStackSlot(int index);
   void StoreDoubleStackSlot(int index);
   void StoreLiteral(int literal_id);
   void StoreArgumentsObject(bool args_known, int args_index, int args_length);
+  void StoreJSFrameFunction();
 
   Zone* zone() const { return zone_; }
 
@@ -760,9 +1035,6 @@
   static const char* StringFor(Opcode opcode);
 #endif
 
-  // A literal id which refers to the JSFunction itself.
-  static const int kSelfLiteralId = -239;
-
  private:
   TranslationBuffer* buffer_;
   int index_;
@@ -770,122 +1042,6 @@
 };
 
 
-class SlotRef BASE_EMBEDDED {
- public:
-  enum SlotRepresentation {
-    UNKNOWN,
-    TAGGED,
-    INT32,
-    UINT32,
-    DOUBLE,
-    LITERAL,
-    DEFERRED_OBJECT,   // Object captured by the escape analysis.
-                       // The number of nested objects can be obtained
-                       // with the DeferredObjectLength() method
-                       // (the SlotRefs of the nested objects follow
-                       // this SlotRef in the depth-first order.)
-    DUPLICATE_OBJECT,  // Duplicated object of a deferred object.
-    ARGUMENTS_OBJECT   // Arguments object - only used to keep indexing
-                       // in sync, it should not be materialized.
-  };
-
-  SlotRef()
-      : addr_(NULL), representation_(UNKNOWN) { }
-
-  SlotRef(Address addr, SlotRepresentation representation)
-      : addr_(addr), representation_(representation) { }
-
-  SlotRef(Isolate* isolate, Object* literal)
-      : literal_(literal, isolate), representation_(LITERAL) { }
-
-  static SlotRef NewArgumentsObject(int length) {
-    SlotRef slot;
-    slot.representation_ = ARGUMENTS_OBJECT;
-    slot.deferred_object_length_ = length;
-    return slot;
-  }
-
-  static SlotRef NewDeferredObject(int length) {
-    SlotRef slot;
-    slot.representation_ = DEFERRED_OBJECT;
-    slot.deferred_object_length_ = length;
-    return slot;
-  }
-
-  SlotRepresentation Representation() { return representation_; }
-
-  static SlotRef NewDuplicateObject(int id) {
-    SlotRef slot;
-    slot.representation_ = DUPLICATE_OBJECT;
-    slot.duplicate_object_id_ = id;
-    return slot;
-  }
-
-  int GetChildrenCount() {
-    if (representation_ == DEFERRED_OBJECT ||
-        representation_ == ARGUMENTS_OBJECT) {
-      return deferred_object_length_;
-    } else {
-      return 0;
-    }
-  }
-
-  int DuplicateObjectId() { return duplicate_object_id_; }
-
-  Handle<Object> GetValue(Isolate* isolate);
-
- private:
-  Address addr_;
-  Handle<Object> literal_;
-  SlotRepresentation representation_;
-  int deferred_object_length_;
-  int duplicate_object_id_;
-};
-
-class SlotRefValueBuilder BASE_EMBEDDED {
- public:
-  SlotRefValueBuilder(
-      JavaScriptFrame* frame,
-      int inlined_frame_index,
-      int formal_parameter_count);
-
-  void Prepare(Isolate* isolate);
-  Handle<Object> GetNext(Isolate* isolate, int level);
-  void Finish(Isolate* isolate);
-
-  int args_length() { return args_length_; }
-
- private:
-  List<Handle<Object> > materialized_objects_;
-  Handle<FixedArray> previously_materialized_objects_;
-  int prev_materialized_count_;
-  Address stack_frame_id_;
-  List<SlotRef> slot_refs_;
-  int current_slot_;
-  int args_length_;
-  int first_slot_index_;
-
-  static SlotRef ComputeSlotForNextArgument(
-      Translation::Opcode opcode,
-      TranslationIterator* iterator,
-      DeoptimizationInputData* data,
-      JavaScriptFrame* frame);
-
-  Handle<Object> GetPreviouslyMaterialized(Isolate* isolate, int length);
-
-  static Address SlotAddress(JavaScriptFrame* frame, int slot_index) {
-    if (slot_index >= 0) {
-      const int offset = JavaScriptFrameConstants::kLocal0Offset;
-      return frame->fp() + offset - (slot_index * kPointerSize);
-    } else {
-      const int offset = JavaScriptFrameConstants::kLastParameterOffset;
-      return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
-    }
-  }
-
-  Handle<Object> GetDeferredObject(Isolate* isolate);
-};
-
 class MaterializedObjectStore {
  public:
   explicit MaterializedObjectStore(Isolate* isolate) : isolate_(isolate) {
@@ -893,7 +1049,7 @@
 
   Handle<FixedArray> Get(Address fp);
   void Set(Address fp, Handle<FixedArray> materialized_objects);
-  void Remove(Address fp);
+  bool Remove(Address fp);
 
  private:
   Isolate* isolate() { return isolate_; }
@@ -985,6 +1141,7 @@
   friend class Deoptimizer;
 };
 
-} }  // namespace v8::internal
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_DEOPTIMIZER_H_