deoptimizer.cc revision f2e3994fa5148cc3d9946666f0b0596290192b0e
1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 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.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/deoptimizer.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/accessors.h"
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/prettyprinter.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/disasm.h"
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames-inl.h"
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/full-codegen/full-codegen.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h"
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/profiler/cpu-profiler.h"
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/v8.h"
17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 {
20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal {
21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic MemoryChunk* AllocateCodeChunk(MemoryAllocator* allocator) {
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return allocator->AllocateChunk(Deoptimizer::GetMaxDeoptTableSize(),
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  base::OS::CommitPageSize(),
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(__native_client__)
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The Native Client port of V8 uses an interpreter,
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // so code pages don't need PROT_EXEC.
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  NOT_EXECUTABLE,
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  EXECUTABLE,
313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  NULL);
3344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDeoptimizerData::DeoptimizerData(MemoryAllocator* allocator)
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : allocator_(allocator),
38f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      deoptimized_frame_info_(NULL),
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      current_(NULL) {
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < Deoptimizer::kBailoutTypesWithCodeEntry; ++i) {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt_entry_code_entries_[i] = -1;
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt_entry_code_[i] = AllocateCodeChunk(allocator);
4344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDeoptimizerData::~DeoptimizerData() {
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < Deoptimizer::kBailoutTypesWithCodeEntry; ++i) {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocator_->Free(deopt_entry_code_[i]);
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt_entry_code_[i] = NULL;
5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
55f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochvoid DeoptimizerData::Iterate(ObjectVisitor* v) {
56f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  if (deoptimized_frame_info_ != NULL) {
57f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    deoptimized_frame_info_->Iterate(v);
58f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  }
59f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch}
60f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
61f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* Deoptimizer::FindDeoptimizingCode(Address addr) {
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (function_->IsHeapObject()) {
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Search all deoptimizing code in the native context of the function.
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = function_->context()->native_context();
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* element = native_context->DeoptimizedCodeListHead();
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (!element->IsUndefined()) {
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = Code::cast(element);
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (code->contains(addr)) return code;
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      element = code->next_code_link();
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// We rely on this function not causing a GC.  It is called from generated code
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// without having a real stack frame in place.
80b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer* Deoptimizer::New(JSFunction* function,
81b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              BailoutType type,
82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              unsigned bailout_id,
83b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              Address from,
8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                              int fp_to_sp_delta,
8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block                              Isolate* isolate) {
8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Deoptimizer* deoptimizer = new Deoptimizer(isolate,
8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                             function,
8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                             type,
8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                             bailout_id,
9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                             from,
913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                             fp_to_sp_delta,
923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                             NULL);
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(isolate->deoptimizer_data()->current_ == NULL);
9444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->deoptimizer_data()->current_ = deoptimizer;
95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return deoptimizer;
96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// No larger than 2K on all platforms
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kDeoptTableMaxEpilogueCodeSize = 2 * KB;
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t Deoptimizer::GetMaxDeoptTableSize() {
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int entries_size =
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_;
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int commit_page_size = static_cast<int>(base::OS::CommitPageSize());
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) /
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    commit_page_size) + 1;
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<size_t>(commit_page_size * page_count);
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDeoptimizer* Deoptimizer::Grab(Isolate* isolate) {
11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Deoptimizer* result = isolate->deoptimizer_data()->current_;
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NOT_NULL(result);
116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  result->DeleteFrameDescriptions();
11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->deoptimizer_data()->current_ = NULL;
118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) {
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (jsframe_index == 0) return 0;
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int frame_index = 0;
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (jsframe_index >= 0) {
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FrameDescription* frame = output_[frame_index];
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) {
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      jsframe_index--;
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    frame_index++;
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return frame_index - 1;
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochDeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
1393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    JavaScriptFrame* frame,
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int jsframe_index,
1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    Isolate* isolate) {
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame->is_optimized());
143f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL);
144f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
145f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Get the function and code from the frame.
146f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  JSFunction* function = frame->function();
147f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Code* code = frame->LookupCode();
148f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
149f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Locate the deoptimization point in the code. As we are at a call the
150f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // return address must be at a place in the code with deoptimization support.
151f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc());
152f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  int deoptimization_index = safepoint_entry.deoptimization_index();
153f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK_NE(deoptimization_index, Safepoint::kNoDeoptimizationIndex);
154f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
155f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Always use the actual stack slots when calculating the fp to sp
156f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // delta adding two for the function and context.
157f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned stack_slots = code->stack_slots();
158f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned arguments_stack_height =
159f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      Deoptimizer::ComputeOutgoingArgumentSize(code, deoptimization_index);
160f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned fp_to_sp_delta = (stack_slots * kPointerSize) +
161f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                            StandardFrameConstants::kFixedFrameSizeFromFp +
162f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                            arguments_stack_height;
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
164f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Deoptimizer* deoptimizer = new Deoptimizer(isolate,
165f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                             function,
166f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                             Deoptimizer::DEBUGGER,
167f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                             deoptimization_index,
168f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                             frame->pc(),
169f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                             fp_to_sp_delta,
170f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                             code);
171f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Address tos = frame->fp() - fp_to_sp_delta;
172f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  deoptimizer->FillInputFrame(tos, frame);
1733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
174f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Calculate the output frames.
175f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Deoptimizer::ComputeOutputFrames(deoptimizer);
176f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
177f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Create the GC safe output frame information and register it for GC
178f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // handling.
179f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK_LT(jsframe_index, deoptimizer->jsframe_count());
180f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
181f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Convert JS frame index into frame index.
182f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index);
183f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
184f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  bool has_arguments_adaptor =
185f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      frame_index > 0 &&
186f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      deoptimizer->output_[frame_index - 1]->GetFrameType() ==
187f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      StackFrame::ARGUMENTS_ADAPTOR;
188f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
189f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  int construct_offset = has_arguments_adaptor ? 2 : 1;
190f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  bool has_construct_stub =
191f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      frame_index >= construct_offset &&
192f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      deoptimizer->output_[frame_index - construct_offset]->GetFrameType() ==
193f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      StackFrame::CONSTRUCT;
194f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
195f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  DeoptimizedFrameInfo* info = new DeoptimizedFrameInfo(deoptimizer,
196f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                                        frame_index,
197f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                                        has_arguments_adaptor,
198f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                                        has_construct_stub);
199f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  isolate->deoptimizer_data()->deoptimized_frame_info_ = info;
200f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
201f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Done with the GC-unsafe frame descriptions. This re-enables allocation.
202f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  deoptimizer->DeleteFrameDescriptions();
203f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
204f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Allocate a heap number for the doubles belonging to this frame.
205f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame(
206f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      frame_index, info->parameters_count(), info->expression_count(), info);
207f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
208f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Finished using the deoptimizer instance.
209f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  delete deoptimizer;
2103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return info;
2123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
2133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
2163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                 Isolate* isolate) {
217f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK_EQ(isolate->deoptimizer_data()->deoptimized_frame_info_, info);
2183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  delete info;
219f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL;
2203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                int count,
225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                BailoutType type) {
226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TableEntryGenerator generator(masm, type, count);
227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  generator.Generate();
228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::VisitAllOptimizedFunctionsForContext(
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* context, OptimizedFunctionVisitor* visitor) {
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(context->IsNativeContext());
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  visitor->EnterContext(context);
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit the list of optimized functions, removing elements that
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // no longer refer to optimized code.
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSFunction* prev = NULL;
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* element = context->OptimizedFunctionsListHead();
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!element->IsUndefined()) {
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    JSFunction* function = JSFunction::cast(element);
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* next = function->next_function_link();
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (function->code()->kind() != Code::OPTIMIZED_FUNCTION ||
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (visitor->VisitFunction(function),
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         function->code()->kind() != Code::OPTIMIZED_FUNCTION)) {
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The function no longer refers to optimized code, or the visitor
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // changed the code to which it refers to no longer be optimized code.
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Remove the function from this list.
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (prev != NULL) {
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        prev->set_next_function_link(next, UPDATE_WEAK_WRITE_BARRIER);
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        context->SetOptimizedFunctionsListHead(next);
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The visitor should not alter the link directly.
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK_EQ(function->next_function_link(), next);
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Set the next function link to undefined to indicate it is no longer
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // in the optimized functions list.
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      function->set_next_function_link(context->GetHeap()->undefined_value(),
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       SKIP_WRITE_BARRIER);
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The visitor should not alter the link directly.
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK_EQ(function->next_function_link(), next);
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // preserve this element.
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      prev = function;
268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element = next;
270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  visitor->LeaveContext(context);
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::VisitAllOptimizedFunctions(
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    OptimizedFunctionVisitor* visitor) {
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Run through the list of all native contexts.
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!context->IsUndefined()) {
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor);
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Unlink functions referring to code marked for deoptimization, then move
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// marked code from the optimized code list to the deoptimized code list,
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and patch code for lazy deopt.
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) {
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A "closure" that unlinks optimized code that is going to be
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deoptimized from the functions that refer to it.
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class SelectedCodeUnlinker: public OptimizedFunctionVisitor {
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void EnterContext(Context* context) { }  // Don't care.
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void LeaveContext(Context* context)  { }  // Don't care.
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void VisitFunction(JSFunction* function) {
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = function->code();
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!code->marked_for_deoptimization()) return;
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Unlink this function and evict from optimized code map.
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SharedFunctionInfo* shared = function->shared();
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function->set_code(shared->code());
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_trace_deopt) {
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(), "[deoptimizer unlinked: ");
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        function->PrintName(scope.file());
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(),
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Unlink all functions that refer to marked code.
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SelectedCodeUnlinker unlinker;
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitAllOptimizedFunctionsForContext(context, &unlinker);
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate = context->GetHeap()->isolate();
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* topmost_optimized_code = NULL;
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool safe_to_deopt_topmost_optimized_code = false;
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Make sure all activations of optimized code can deopt at their current PC.
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The topmost optimized code has special handling because it cannot be
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deoptimized due to weak object dependency.
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (StackFrameIterator it(isolate, isolate->thread_local_top());
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       !it.done(); it.Advance()) {
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StackFrame::Type type = it.frame()->type();
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (type == StackFrame::OPTIMIZED) {
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = it.frame()->LookupCode();
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      JSFunction* function =
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<OptimizedFrame*>(it.frame())->function();
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_trace_deopt) {
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CodeTracer::Scope scope(isolate->GetCodeTracer());
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(), "[deoptimizer found activation of function: ");
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        function->PrintName(scope.file());
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(),
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SafepointEntry safepoint = code->GetSafepointEntry(it.frame()->pc());
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int deopt_index = safepoint.deoptimization_index();
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Turbofan deopt is checked when we are patching addresses on stack.
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool turbofanned = code->is_turbofanned() &&
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         function->shared()->asm_function() &&
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         !FLAG_turbo_asm_deoptimization;
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool safe_to_deopt =
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          deopt_index != Safepoint::kNoDeoptimizationIndex || turbofanned;
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(topmost_optimized_code == NULL || safe_to_deopt || turbofanned);
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (topmost_optimized_code == NULL) {
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        topmost_optimized_code = code;
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        safe_to_deopt_topmost_optimized_code = safe_to_deopt;
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Move marked code from the optimized code list to the deoptimized
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code list, collecting them into a ZoneList.
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone zone;
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Code*> codes(10, &zone);
366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Walk over all optimized code objects in this native context.
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* prev = NULL;
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* element = context->OptimizedCodeListHead();
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!element->IsUndefined()) {
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* code = Code::cast(element);
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* next = code->next_code_link();
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (code->marked_for_deoptimization()) {
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Put the code into the list for later patching.
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      codes.Add(code, &zone);
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (prev != NULL) {
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Skip this code in the optimized code list.
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        prev->set_next_code_link(next);
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // There was no previous node, the next node is the new head.
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        context->SetOptimizedCodeListHead(next);
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Move the code to the _deoptimized_ code list.
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code->set_next_code_link(context->DeoptimizedCodeListHead());
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      context->SetDeoptimizedCodeListHead(code);
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Not marked; preserve this element.
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      prev = code;
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element = next;
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
397f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // TODO(titzer): we need a handle scope only because of the macro assembler,
398f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // which is only used in EnsureCodeForDeoptimizationEntry.
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate);
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Now patch all the codes for deoptimization.
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < codes.length(); i++) {
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (codes[i] == topmost_optimized_code) {
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(safe_to_deopt_topmost_optimized_code);
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // It is finally time to die, code object.
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Remove the code from optimized code map.
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizationInputData* deopt_data =
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DeoptimizationInputData::cast(codes[i]->deoptimization_data());
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SharedFunctionInfo* shared =
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo());
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    shared->EvictFromOptimizedCodeMap(codes[i], "deoptimized code");
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Do platform-specific patching to force any activations to lazy deopt.
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PatchCodeForDeoptimization(isolate, codes[i]);
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We might be in the middle of incremental marking with compaction.
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Tell collector to treat this code object in a special way and
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // ignore all slots that might have been recorded on it.
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]);
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeAll(Isolate* isolate) {
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trace_deopt) {
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CodeTracer::Scope scope(isolate->GetCodeTracer());
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(scope.file(), "[deoptimize all code in all contexts]\n");
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For all contexts, mark all code, then deoptimize.
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!context->IsUndefined()) {
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = Context::cast(context);
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkAllCodeForContext(native_context);
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizeMarkedCodeForContext(native_context);
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    context = native_context->get(Context::NEXT_CONTEXT_LINK);
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) {
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trace_deopt) {
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CodeTracer::Scope scope(isolate->GetCodeTracer());
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(scope.file(), "[deoptimize marked code in all contexts]\n");
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For all contexts, deoptimize code already marked.
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!context->IsUndefined()) {
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = Context::cast(context);
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizeMarkedCodeForContext(native_context);
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    context = native_context->get(Context::NEXT_CONTEXT_LINK);
457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::MarkAllCodeForContext(Context* context) {
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* element = context->OptimizedCodeListHead();
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!element->IsUndefined()) {
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* code = Code::cast(element);
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code->set_marked_for_deoptimization(true);
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element = code->next_code_link();
468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeFunction(JSFunction* function) {
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* code = function->code();
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (code->kind() == Code::OPTIMIZED_FUNCTION) {
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Mark the code for deoptimization and unlink any functions that also
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // refer to that code. The code cannot be shared across native contexts,
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // so we only need to search one.
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code->set_marked_for_deoptimization(true);
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizeMarkedCodeForContext(function->context()->native_context());
480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  deoptimizer->DoComputeOutputFrames();
486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Deoptimizer::TraceEnabledFor(BailoutType deopt_type,
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  StackFrame::Type frame_type) {
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (deopt_type) {
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EAGER:
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SOFT:
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LAZY:
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DEBUGGER:
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return (frame_type == StackFrame::STUB)
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ? FLAG_trace_stub_failures
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : FLAG_trace_deopt;
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("Unsupported deopt type");
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* Deoptimizer::MessageFor(BailoutType type) {
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (type) {
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EAGER: return "eager";
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SOFT: return "soft";
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LAZY: return "lazy";
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DEBUGGER: return "debugger";
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("Unsupported deopt type");
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
516f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDeoptimizer::Deoptimizer(Isolate* isolate, JSFunction* function,
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         BailoutType type, unsigned bailout_id, Address from,
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         int fp_to_sp_delta, Code* optimized_code)
52044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : isolate_(isolate),
52144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      function_(function),
522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bailout_id_(bailout_id),
523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bailout_type_(type),
524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      from_(from),
525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      fp_to_sp_delta_(fp_to_sp_delta),
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      has_alignment_padding_(0),
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      input_(nullptr),
528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_count_(0),
5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      jsframe_count_(0),
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_(nullptr),
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      trace_scope_(nullptr) {
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For COMPILED_STUBs called from builtins, the function pointer is a SMI
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // indicating an internal frame.
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (function->IsSmi()) {
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    function = nullptr;
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(from != nullptr);
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (function != nullptr && function->IsOptimized()) {
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    function->shared()->increment_deopt_count();
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (bailout_type_ == Deoptimizer::SOFT) {
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->counters()->soft_deopts_executed()->Increment();
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Soft deopts shouldn't count against the overall re-optimization count
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // that can eventually lead to disabling optimization for a function.
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int opt_count = function->shared()->opt_count();
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (opt_count > 0) opt_count--;
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function->shared()->set_opt_count(opt_count);
5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compiled_code_ = FindOptimizedCode(function, optimized_code);
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if DEBUG
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(compiled_code_ != NULL);
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == EAGER || type == SOFT || type == LAZY) {
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(compiled_code_->kind() != Code::FUNCTION);
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackFrame::Type frame_type = function == NULL
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? StackFrame::STUB
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : StackFrame::JAVA_SCRIPT;
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  trace_scope_ = TraceEnabledFor(type, frame_type) ?
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL;
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(AllowHeapAllocation::IsAllowed());
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  disallow_heap_allocation_ = new DisallowHeapAllocation();
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PROFILE(isolate_, CodeDeoptEvent(compiled_code_, from_, fp_to_sp_delta_));
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned size = ComputeInputFrameSize();
570f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  input_ = new(size) FrameDescription(size, function);
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_->SetFrameType(frame_type);
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* Deoptimizer::FindOptimizedCode(JSFunction* function,
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Code* optimized_code) {
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (bailout_type_) {
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Deoptimizer::SOFT:
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Deoptimizer::EAGER:
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Deoptimizer::LAZY: {
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* compiled_code = FindDeoptimizingCode(from_);
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return (compiled_code == NULL)
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ? static_cast<Code*>(isolate_->FindCodeObject(from_))
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : compiled_code;
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Deoptimizer::DEBUGGER:
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(optimized_code->contains(from_));
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return optimized_code;
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("Could not find code for optimized function");
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::PrintFunctionName() {
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (function_->IsJSFunction()) {
597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    function_->ShortPrint(trace_scope_->file());
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "%s", Code::Kind2String(compiled_code_->kind()));
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer::~Deoptimizer() {
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(input_ == NULL && output_ == NULL);
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(disallow_heap_allocation_ == NULL);
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete trace_scope_;
609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DeleteFrameDescriptions() {
613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete input_;
614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < output_count_; ++i) {
615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (output_[i] != input_) delete output_[i];
616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete[] output_;
618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  input_ = NULL;
619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  output_ = NULL;
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(!AllowHeapAllocation::IsAllowed());
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(disallow_heap_allocation_ != NULL);
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete disallow_heap_allocation_;
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  disallow_heap_allocation_ = NULL;
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            int id,
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            BailoutType type,
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            GetEntryMode mode) {
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_GE(id, 0);
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (id >= kMaxNumberOfEntries) return NULL;
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == ENSURE_ENTRY_CODE) {
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EnsureCodeForDeoptimizationEntry(isolate, type, id);
637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_EQ(mode, CALCULATE_ENTRY_ADDRESS);
639b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeoptimizerData* data = isolate->deoptimizer_data();
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_LT(type, kBailoutTypesWithCodeEntry);
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* base = data->deopt_entry_code_[type];
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return base->area_start() + (id * table_entry_size_);
644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Deoptimizer::GetDeoptimizationId(Isolate* isolate,
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Address addr,
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     BailoutType type) {
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeoptimizerData* data = isolate->deoptimizer_data();
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* base = data->deopt_entry_code_[type];
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address start = base->area_start();
653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (addr < start ||
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addr >= start + (kMaxNumberOfEntries * table_entry_size_)) {
655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return kNotDeoptimizationEntry;
656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(0,
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            static_cast<int>(addr - start) % table_entry_size_);
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<int>(addr - start) / table_entry_size_;
660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6639fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockint Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               BailoutId id,
6659fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                               SharedFunctionInfo* shared) {
666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // TODO(kasperl): For now, we do a simple linear search for the PC
667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // offset associated with the given node id. This should probably be
668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // changed to a binary search.
669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = data->DeoptPoints();
670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < length; i++) {
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (data->AstId(i) == id) {
672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return data->PcAndState(i)->value();
673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OFStream os(stderr);
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os << "[couldn't find pc offset for node=" << id.ToInt() << "]\n"
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     << "[method: " << shared->DebugName()->ToCString().get() << "]\n"
678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier     << "[source:\n" << SourceCodeOf(shared) << "\n]" << std::endl;
679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  shared->GetHeap()->isolate()->PushStackTraceAndDie(0xfefefefe, data, shared,
681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                     0xfefefeff);
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("unable to find pc offset during deoptimization");
683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return -1;
684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
68744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) {
688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = 0;
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Count all entries in the deoptimizing code list of every context.
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!context->IsUndefined()) {
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = Context::cast(context);
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* element = native_context->DeoptimizedCodeListHead();
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (!element->IsUndefined()) {
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = Code::cast(element);
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      length++;
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      element = code->next_code_link();
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
702b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return length;
703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
704b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// We rely on this function not causing a GC.  It is called from generated code
7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// without having a real stack frame in place.
708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DoComputeOutputFrames() {
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::ElapsedTimer timer;
710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Determine basic deoptimization information.  The optimized frame is
712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // described by the input data.
713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizationInputData* input_data =
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DeoptimizationInputData::cast(compiled_code_->deoptimization_data());
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    timer.Start();
718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ",
719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           MessageFor(bailout_type_));
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintFunctionName();
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           " (opt #%d) @%d, FP to SP delta: %d]\n",
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           input_data->OptimizationId()->value(),
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           bailout_id_,
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           fp_to_sp_delta_);
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (bailout_type_ == EAGER || bailout_type_ == SOFT ||
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (compiled_code_->is_hydrogen_stub())) {
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      compiled_code_->PrintDeoptLocation(trace_scope_->file(), from_);
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId node_id = input_data->AstId(bailout_id_);
733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ByteArray* translations = input_data->TranslationByteArray();
734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned translation_index =
735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      input_data->TranslationIndex(bailout_id_)->value();
736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslationIterator state_iterator(translations, translation_index);
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  translated_state_.Init(
739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      input_->GetFramePointerAddress(), &state_iterator,
740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      input_data->LiteralArray(), input_->GetRegisterValues(),
741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      trace_scope_ == nullptr ? nullptr : trace_scope_->file());
742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Do the input frame to output frame(s) translation.
744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t count = translated_state_.frames().size();
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(output_ == NULL);
746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  output_ = new FrameDescription*[count];
747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < count; ++i) {
748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    output_[i] = NULL;
749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_count_ = static_cast<int>(count);
751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register fp_reg = JavaScriptFrame::fp_register();
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stack_fp_ = reinterpret_cast<Address>(
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      input_->GetRegister(fp_reg.code()) +
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          has_alignment_padding_ * kPointerSize);
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
757b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Translate each output frame.
758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < count; ++i) {
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Read the ast node id, function, and frame height for this output frame.
760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int frame_index = static_cast<int>(i);
761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (translated_state_.frames()[i].kind()) {
762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kFunction:
763f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch        DoComputeJSFrame(frame_index);
7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        jsframe_count_++;
7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kInterpretedFunction:
767f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch        DoComputeInterpretedFrame(frame_index);
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        jsframe_count_++;
769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kArgumentsAdaptor:
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeArgumentsAdaptorFrame(frame_index);
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kConstructStub:
774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeConstructStubFrame(frame_index);
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kGetter:
777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeAccessorStubFrame(frame_index, false);
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kSetter:
780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeAccessorStubFrame(frame_index, true);
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kCompiledStub:
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeCompiledStubFrame(frame_index);
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kInvalid:
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FATAL("invalid frame");
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Print some helpful diagnostic information.
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double ms = timer.Elapsed().InMillisecondsF();
794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int index = output_count_ - 1;  // Index of the topmost frame.
795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF(trace_scope_->file(), "[deoptimizing (%s): end ",
796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           MessageFor(bailout_type_));
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintFunctionName();
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           " took %0.3f ms]\n",
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           bailout_id_,
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           node_id.ToInt(),
803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           output_[index]->GetPc(),
804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           FullCodeGenerator::State2String(
805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               static_cast<FullCodeGenerator::State>(
806b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                   output_[index]->GetState()->value())),
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           has_alignment_padding_ ? "with padding" : "no padding",
808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           ms);
809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
810b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
812f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
813f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochvoid Deoptimizer::DoComputeJSFrame(int frame_index) {
814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId node_id = translated_frame->node_id();
820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height =
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translated_frame->height() - 1;  // Do not count the context.
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "  translating frame ");
828f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    function->PrintName(trace_scope_->file());
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The 'fixed' part of the frame consists of the incoming parameters and
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the part described by JavaScriptFrameConstants.
835f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned fixed_frame_size = ComputeJavascriptFixedSize(function);
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned input_frame_size = input_->GetFrameSize();
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
840f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  FrameDescription* output_frame =
841f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      new(output_frame_size) FrameDescription(output_frame_size, function);
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
844f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  bool is_bottommost = (0 == frame_index);
845f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  bool is_topmost = (output_count_ - 1 == frame_index);
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame_index >= 0 && frame_index < output_count_);
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NULL(output_[frame_index]);
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address for the bottommost output frame can be computed from
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the input frame pointer and the output frame's height.  For all
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // subsequent output frames, it can be computed from the previous one's
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // top address and the current frame's size.
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register fp_reg = JavaScriptFrame::fp_register();
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address;
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_bottommost) {
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Determine whether the input frame contains alignment padding.
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_alignment_padding_ =
859f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch        (!compiled_code_->is_turbofanned() && HasAlignmentPadding(function))
860f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch            ? 1
861f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch            : 0;
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // 2 = context and function in the frame.
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the optimized frame had alignment padding, adjust the frame pointer
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // to point to the new position of the old frame pointer after padding
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // is removed. Subtract 2 * kPointerSize for the context and function slots.
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    top_address = input_->GetRegister(fp_reg.code()) -
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        StandardFrameConstants::kFixedFrameSizeFromFp -
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        height_in_bytes + has_alignment_padding_ * kPointerSize;
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the incoming parameter translation.
875f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  int parameter_count =
876f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      function->shared()->internal_formal_parameter_count() + 1;
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned input_offset = input_frame_size;
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= (parameter_count * kPointerSize);
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There are no translation commands for the caller's pc and fp, the
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // context, and the function.  Synthesize their values and set them up
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // explicitly.
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The caller's pc for the bottommost output frame is the same as in the
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // input frame.  For all subsequent output frames, it can be read from the
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // previous one.  This frame's pc can be computed from the non-optimized
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // function code and AST id of the bailout.
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= kPCOnStackSize;
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value;
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_bottommost) {
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = input_->GetFrameSlot(input_offset);
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetPc();
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, value);
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The caller's frame pointer for the bottommost output frame is the same
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // as in the input frame.  For all subsequent output frames, it can be
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // read from the previous one.  Also compute and set this frame's frame
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // pointer.
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= kFPOnStackSize;
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_bottommost) {
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = input_->GetFrameSlot(input_offset);
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetFp();
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!is_bottommost || (input_->GetRegister(fp_reg.code()) +
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      has_alignment_padding_ * kPointerSize) == fp_value);
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!is_bottommost || !has_alignment_padding_ ||
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (fp_value & kPointerSize) != 0);
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // For the bottommost output frame the constant pool pointer can be gotten
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // from the input frame. For subsequent output frames, it can be read from
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the previous frame.
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    input_offset -= kPointerSize;
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_bottommost) {
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value = input_->GetFrameSlot(input_offset);
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value = output_[frame_index - 1]->GetConstantPool();
9368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For the bottommost output frame the context can be gotten from the input
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame. For all subsequent output frames it can be gotten from the function
944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // so long as we don't inline functions that need local contexts.
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register context_reg = JavaScriptFrame::context_register();
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= kPointerSize;
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read the context from the translations.
949f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Object* context = value_iterator->GetRawValue();
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (context == isolate_->heap()->undefined_value()) {
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the context was optimized away, just use the context from
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the activation. This should only apply to Crankshaft code.
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!compiled_code_->is_turbofanned());
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    context =
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        is_bottommost
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ? reinterpret_cast<Object*>(input_->GetFrameSlot(input_offset))
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            : function->context();
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(context);
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetContext(value);
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_topmost) output_frame->SetRegister(context_reg.code(), value);
962f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  WriteValueToOutput(context, input_index, frame_index, output_offset,
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "context    ");
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (context == isolate_->heap()->arguments_marker()) {
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address =
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        output_offset;
968f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    values_to_materialize_.push_back({output_address, value_iterator});
969b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The function was mentioned explicitly in the BEGIN_FRAME.
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= kPointerSize;
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(function);
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The function for the bottommost output frame should also agree with the
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // input frame.
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Translate the rest of the frame.
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (unsigned i = 0; i < height; ++i) {
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_offset);
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
990f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Compute this frame's PC, state, and continuation.
991f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Code* non_optimized_code = function->shared()->code();
992f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  FixedArray* raw_data = non_optimized_code->deoptimization_data();
993f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
994f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Address start = non_optimized_code->instruction_start();
995f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
996f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
997f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
998f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  output_frame->SetPc(pc_value);
999f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update constant pool.
1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(non_optimized_code->constant_pool());
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_topmost) {
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Register constant_pool_reg =
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          JavaScriptFrame::constant_pool_pointer_register();
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
10113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FullCodeGenerator::State state =
1013f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      FullCodeGenerator::StateField::decode(pc_and_state);
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetState(Smi::FromInt(state));
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set the continuation for the topmost frame.
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_topmost && bailout_type_ != DEBUGGER) {
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Builtins* builtins = isolate_->builtins();
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (bailout_type_ == LAZY) {
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (bailout_type_ == SOFT) {
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK_EQ(bailout_type_, EAGER);
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetContinuation(
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(continuation->entry()));
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
10313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1032f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1033f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochvoid Deoptimizer::DoComputeInterpretedFrame(int frame_index) {
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1039f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  BailoutId bytecode_offset = translated_frame->node_id();
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = translated_frame->height();
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height_in_bytes = height * kPointerSize;
1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
1043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != NULL) {
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "  translating interpreted frame ");
1047f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    function->PrintName(trace_scope_->file());
1048f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d\n",
1049f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch           bytecode_offset.ToInt(), height_in_bytes);
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The 'fixed' part of the frame consists of the incoming parameters and
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the part described by InterpreterFrameConstants.
1054f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned fixed_frame_size = ComputeInterpretedFixedSize(function);
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned input_frame_size = input_->GetFrameSize();
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate and store the output frame description.
1059f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  FrameDescription* output_frame =
1060f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      new (output_frame_size) FrameDescription(output_frame_size, function);
1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetFrameType(StackFrame::INTERPRETED);
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_bottommost = (0 == frame_index);
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_topmost = (output_count_ - 1 == frame_index);
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(frame_index >= 0 && frame_index < output_count_);
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NULL(output_[frame_index]);
1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_[frame_index] = output_frame;
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The top address for the bottommost output frame can be computed from
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the input frame pointer and the output frame's height.  For all
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // subsequent output frames, it can be computed from the previous one's
1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // top address and the current frame's size.
1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register fp_reg = InterpretedFrame::fp_register();
1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t top_address;
1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_bottommost) {
1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Subtract interpreter fixed frame size for the context function slots,
1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // new,target and bytecode offset.
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    top_address = input_->GetRegister(fp_reg.code()) -
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  InterpreterFrameConstants::kFixedFrameSizeFromFp -
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  height_in_bytes;
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetTop(top_address);
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Compute the incoming parameter translation.
1087f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  int parameter_count =
1088f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      function->shared()->internal_formal_parameter_count() + 1;
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned output_offset = output_frame_size;
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned input_offset = input_frame_size;
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < parameter_count; ++i) {
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_offset -= kPointerSize;
1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= (parameter_count * kPointerSize);
1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // There are no translation commands for the caller's pc and fp, the
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // context, the function, new.target and the bytecode offset.  Synthesize
1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // their values and set them up
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // explicitly.
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The caller's pc for the bottommost output frame is the same as in the
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // input frame.  For all subsequent output frames, it can be read from the
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // previous one.  This frame's pc can be computed from the non-optimized
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // function code and AST id of the bailout.
1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPCOnStackSize;
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPCOnStackSize;
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t value;
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_bottommost) {
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = input_->GetFrameSlot(input_offset);
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = output_[frame_index - 1]->GetPc();
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetCallerPc(output_offset, value);
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The caller's frame pointer for the bottommost output frame is the same
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // as in the input frame.  For all subsequent output frames, it can be
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // read from the previous one.  Also compute and set this frame's frame
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointer.
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kFPOnStackSize;
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kFPOnStackSize;
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_bottommost) {
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = input_->GetFrameSlot(input_offset);
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = output_[frame_index - 1]->GetFp();
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetCallerFp(output_offset, value);
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t fp_value = top_address + output_offset;
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!is_bottommost ||
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         (input_->GetRegister(fp_reg.code()) +
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          has_alignment_padding_ * kPointerSize) == fp_value);
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetFp(fp_value);
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!is_bottommost || !has_alignment_padding_ ||
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         (fp_value & kPointerSize) != 0);
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // For the bottommost output frame the constant pool pointer can be gotten
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // from the input frame. For subsequent output frames, it can be read from
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // the previous frame.
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_offset -= kPointerSize;
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    input_offset -= kPointerSize;
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_bottommost) {
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value = input_->GetFrameSlot(input_offset);
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value = output_[frame_index - 1]->GetConstantPool();
1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // For the bottommost output frame the context can be gotten from the input
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // frame. For all subsequent output frames it can be gotten from the function
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // so long as we don't inline functions that need local contexts.
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register context_reg = InterpretedFrame::context_register();
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPointerSize;
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read the context from the translations.
1163f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Object* context = value_iterator->GetRawValue();
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The context should not be a placeholder for a materialized object.
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(context != isolate_->heap()->arguments_marker());
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(context);
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetContext(value);
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_topmost) output_frame->SetRegister(context_reg.code(), value);
1169f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  WriteValueToOutput(context, input_index, frame_index, output_offset,
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "context    ");
1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The function was mentioned explicitly in the BEGIN_FRAME.
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPointerSize;
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(function);
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The function for the bottommost output frame should also agree with the
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // input frame.
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1183f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // TODO(rmcilroy): Deal with new.target correctly - currently just set it to
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // undefined.
1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPointerSize;
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* new_target = isolate_->heap()->undefined_value();
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target  ");
1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The bytecode offset was mentioned explicitly in the BEGIN_FRAME.
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPointerSize;
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int raw_bytecode_offset =
1194f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset.ToInt();
1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset);
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset,
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "bytecode offset ");
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Translate the rest of the interpreter registers in the frame.
1200f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  for (unsigned i = 0; i < height; ++i) {
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_offset -= kPointerSize;
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
12058389745919cae02139ddc085a63c00d024269cf2Ben Murdoch  CHECK_EQ(0u, output_offset);
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1207f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Set the accumulator register.
1208f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  output_frame->SetRegister(
1209f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      kInterpreterAccumulatorRegister.code(),
1210f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      reinterpret_cast<intptr_t>(value_iterator->GetRawValue()));
1211f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  value_iterator++;
1212f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Builtins* builtins = isolate_->builtins();
1214f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Code* trampoline = builtins->builtin(Builtins::kInterpreterEntryTrampoline);
1215f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  output_frame->SetPc(reinterpret_cast<intptr_t>(trampoline->entry()));
1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetState(0);
1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Update constant pool.
1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    intptr_t constant_pool_value =
1221f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch        reinterpret_cast<intptr_t>(trampoline->constant_pool());
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetConstantPool(constant_pool_value);
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_topmost) {
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register constant_pool_reg =
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          InterpretedFrame::constant_pool_pointer_register();
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Set the continuation for the topmost frame.
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_topmost && bailout_type_ != DEBUGGER) {
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Code* continuation =
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        builtins->builtin(Builtins::kInterpreterNotifyDeoptimized);
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (bailout_type_ == LAZY) {
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continuation =
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          builtins->builtin(Builtins::kInterpreterNotifyLazyDeoptimized);
1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (bailout_type_ == SOFT) {
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continuation =
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          builtins->builtin(Builtins::kInterpreterNotifySoftDeoptimized);
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK_EQ(bailout_type_, EAGER);
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetContinuation(
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<intptr_t>(continuation->entry()));
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) {
1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = translated_frame->height();
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating arguments adaptor => height=%d\n", height_in_bytes);
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
1269f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  FrameDescription* output_frame =
1270f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      new(output_frame_size) FrameDescription(output_frame_size, function);
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Arguments adaptor can not be topmost or bottommost.
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame_index > 0 && frame_index < output_count_ - 1);
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(output_[frame_index] == NULL);
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address of the frame is computed from the previous
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame's top and this frame's size.
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address;
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the incoming parameter translation.
1285f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  int parameter_count = height;
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
12923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC from the previous frame.
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, callers_pc);
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
12983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the previous frame, and set this frame's FP.
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = output_[frame_index - 1]->GetFp();
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
13063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the previous frame.
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetConstantPool();
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
13143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A marker value is used in place of the context.
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t context = reinterpret_cast<intptr_t>(
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, context);
1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(context, frame_index, output_offset,
1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "context (adaptor sentinel)\n");
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(function);
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of incoming arguments.
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "argc ");
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "(%d)\n", height - 1);
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(0 == output_offset);
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Builtins* builtins = isolate_->builtins();
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* adaptor_trampoline =
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc_value = reinterpret_cast<intptr_t>(
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      adaptor_trampoline->instruction_start() +
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(pc_value);
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool());
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
13523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
13533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
13543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DoComputeConstructStubFrame(int frame_index) {
1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Builtins* builtins = isolate_->builtins();
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = translated_frame->height();
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
1365f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating construct stub => height=%d\n", height_in_bytes);
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize;
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameDescription* output_frame =
1378f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      new(output_frame_size) FrameDescription(output_frame_size, function);
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::CONSTRUCT);
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Construct stub can not be topmost or bottommost.
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(frame_index > 0 && frame_index < output_count_ - 1);
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(output_[frame_index] == NULL);
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address of the frame is computed from the previous
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame's top and this frame's size.
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address;
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the incoming parameter translation.
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int parameter_count = height;
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The allocated receiver of a construct stub frame is passed as the
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // receiver parameter through the translation. It might be encoding
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // a captured object, override the slot address for a captured object.
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &value_iterator, &input_index, frame_index, output_offset, nullptr,
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (i == 0) ? reinterpret_cast<Address>(top_address) : nullptr);
1403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC from the previous frame.
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, callers_pc);
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
1410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the previous frame, and set this frame's FP.
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = output_[frame_index - 1]->GetFp();
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the previous frame.
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetConstantPool();
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The context can be gotten from the previous frame.
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = output_[frame_index - 1]->GetContext();
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A marker value is used in place of the function.
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset,
1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "function (construct sentinel)\n");
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The output frame reflects a JSConstructStubGeneric frame.
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(construct_stub);
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n");
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The allocation site.
1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(isolate_->heap()->undefined_value());
1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetFrameSlot(output_offset, value);
1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "allocation site\n");
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of incoming arguments.
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "argc ");
1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "(%d)\n", height - 1);
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The newly allocated object was passed as receiver in the artificial
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // constructor stub environment created by HEnvironment::CopyForInlining().
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset,
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "allocated receiver\n");
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_offset);
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc = reinterpret_cast<intptr_t>(
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      construct_stub->instruction_start() +
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->construct_stub_deopt_pc_offset()->value());
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(pc);
1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(construct_stub->constant_pool());
1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DoComputeAccessorStubFrame(int frame_index,
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             bool is_setter_stub_frame) {
1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1491f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  JSFunction* accessor = JSFunction::cast(value_iterator->GetRawValue());
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The receiver (and the implicit return value, if any) are expected in
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // registers by the LoadIC/StoreIC, so they don't belong to the output stack
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame. This means that we have to use a height of 0.
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height = 0;
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* kind = is_setter_stub_frame ? "setter" : "getter";
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating %s stub => height=%u\n", kind, height_in_bytes);
1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We need 1 stack entry for the return address and enough entries for the
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // StackFrame::INTERNAL (FP, context, frame type, code object and constant
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pool (if enabled)- see MacroAssembler::EnterFrame).
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For a setter stub frame we need one additional entry for the implicit
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // return value, see StoreStubCompiler::CompileStoreViaSetter.
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_entries =
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (StandardFrameConstants::kFixedFrameSize / kPointerSize) + 1 +
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (is_setter_stub_frame ? 1 : 0);
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameDescription* output_frame =
1518f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      new(output_frame_size) FrameDescription(output_frame_size, accessor);
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::INTERNAL);
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A frame for an accessor stub can not be the topmost or bottommost one.
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame_index > 0 && frame_index < output_count_ - 1);
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NULL(output_[frame_index]);
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address of the frame is computed from the previous frame's top and
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // this frame's size.
1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC from the previous frame.
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, callers_pc);
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the previous frame, and set this frame's FP.
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = output_[frame_index - 1]->GetFp();
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the previous frame.
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetConstantPool();
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The context can be gotten from the previous frame.
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = output_[frame_index - 1]->GetContext();
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A marker value is used in place of the function.
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "function ");
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "(%s sentinel)\n", kind);
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get Code object from accessor stub.
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Builtins::Name name = is_setter_stub_frame ?
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Builtins::kStoreIC_Setter_ForDeopt :
1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Builtins::kLoadIC_Getter_ForDeopt;
1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* accessor_stub = isolate_->builtins()->builtin(name);
1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(accessor_stub);
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n");
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Skip receiver.
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_setter_stub_frame) {
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The implicit return value was part of the artificial setter stub
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // environment.
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_offset);
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Smi* offset = is_setter_stub_frame ?
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->setter_stub_deopt_pc_offset() :
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->getter_stub_deopt_pc_offset();
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc = reinterpret_cast<intptr_t>(
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      accessor_stub->instruction_start() + offset->value());
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(pc);
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DoComputeCompiledStubFrame(int frame_index) {
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //               FROM                                  TO
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |          ....           |          |          ....           |
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    +-------------------------+          +-------------------------+
1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    | JSFunction continuation |          | JSFunction continuation |
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    +-------------------------+          +-------------------------+
1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  |    saved frame (FP)     |          |    saved frame (FP)     |
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  +=========================+<-fpreg   +=========================+<-fpreg
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  |constant pool (if ool_cp)|          |constant pool (if ool_cp)|
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  +-------------------------+          +-------------------------|
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  |   JSFunction context    |          |   JSFunction context    |
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // v  +-------------------------+          +-------------------------|
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |   COMPILED_STUB marker  |          |   STUB_FAILURE marker   |
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    +-------------------------+          +-------------------------+
1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |                         |          |  caller args.arguments_ |
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    | ...                     |          +-------------------------+
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |                         |          |  caller args.length_    |
1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |-------------------------|<-spreg   +-------------------------+
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         |  caller args pointer    |
1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         +-------------------------+
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         |  caller stack param 1   |
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //      parameters in registers            +-------------------------+
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //       and spilled to stack              |           ....          |
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         +-------------------------+
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         |  caller stack param n   |
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         +-------------------------+<-spreg
1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = number of parameters
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = failure handler address
1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = saved frame
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = JSFunction context
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Caller stack params contain the register parameters to the stub first,
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // and then, if the descriptor specifies a constant number of stack
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // parameters, the stack parameters as well.
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(compiled_code_->is_hydrogen_stub());
1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int major_key = CodeStub::GetMajorKey(compiled_code_);
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeStubDescriptor descriptor(isolate_, compiled_code_->stub_key());
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The output frame must have room for all pushed register parameters
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and the standard stack frame slots.  Include space for an argument
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // object to the callee and optionally the space to pass the argument
1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // object to the stub failure handler.
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int param_count = descriptor.GetRegisterParameterCount();
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int stack_param_count = descriptor.GetStackParameterCount();
1660f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK_EQ(translated_frame->height(), param_count);
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_GE(param_count, 0);
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int height_in_bytes = kPointerSize * (param_count + stack_param_count) +
1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        sizeof(Arguments) + kPointerSize;
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int input_frame_size = input_->GetFrameSize();
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int output_frame_size = height_in_bytes + fixed_frame_size;
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating %s => StubFailureTrampolineStub, height=%d\n",
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           CodeStub::MajorName(static_cast<CodeStub::Major>(major_key)),
1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           height_in_bytes);
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The stub failure trampoline is a single frame.
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameDescription* output_frame =
1677f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      new(output_frame_size) FrameDescription(output_frame_size, NULL);
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_EQ(frame_index, 0);
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address for the output frame can be computed from the input
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame pointer and the output frame's height. Subtract space for the
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // context and function slots.
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register fp_reg = StubFailureTrampolineFrame::fp_register();
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address = input_->GetRegister(fp_reg.code()) -
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes;
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC (JSFunction continuation) from the input frame.
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned input_frame_offset = input_frame_size - kPCOnStackSize;
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_offset = output_frame_size - kFPOnStackSize;
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = input_->GetFrameSlot(input_frame_offset);
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_frame_offset, value);
1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "caller's pc\n");
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the input frame, and set this frame's FP.
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_frame_offset -= kFPOnStackSize;
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = input_->GetFrameSlot(input_frame_offset);
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kFPOnStackSize;
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_frame_offset, value);
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t frame_ptr = input_->GetRegister(fp_reg.code());
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetRegister(fp_reg.code(), frame_ptr);
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(frame_ptr);
1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "caller's fp\n");
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the input frame.
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    input_frame_offset -= kPointerSize;
1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = input_->GetFrameSlot(input_frame_offset);
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame_offset -= kPointerSize;
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_frame_offset, value);
1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1719f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // The context can be gotten from the input frame.
1720f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Register context_reg = StubFailureTrampolineFrame::context_register();
1721f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  input_frame_offset -= kPointerSize;
1722f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  value = input_->GetFrameSlot(input_frame_offset);
1723f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  output_frame->SetRegister(context_reg.code(), value);
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1725f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  output_frame->SetFrameSlot(output_frame_offset, value);
1726f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK(reinterpret_cast<Object*>(value)->IsContext());
1727f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset, "context\n");
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A marker value is used in place of the function.
1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE));
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_frame_offset, value);
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "function (stub failure sentinel)\n");
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t caller_arg_count = stack_param_count;
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool arg_count_known = !descriptor.stack_parameter_count().is_valid();
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Build the Arguments object for the caller's parameters and a pointer to it.
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int args_arguments_offset = output_frame_offset;
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t the_hole = reinterpret_cast<intptr_t>(
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->the_hole_value());
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (arg_count_known) {
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (caller_arg_count - 1) * kPointerSize;
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = the_hole;
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(args_arguments_offset, value);
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(
1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value, frame_index, args_arguments_offset,
1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arg_count_known ? "args.arguments\n" : "args.arguments (the hole)\n");
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int length_frame_offset = output_frame_offset;
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = arg_count_known ? caller_arg_count : the_hole;
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(length_frame_offset, value);
1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(
1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value, frame_index, length_frame_offset,
1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arg_count_known ? "args.length\n" : "args.length (the hole)\n");
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = frame_ptr + StandardFrameConstants::kCallerSPOffset -
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (output_frame_size - output_frame_offset) + kPointerSize;
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_frame_offset, value);
1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset, "args*\n");
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy the register parameters to the failure frame.
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int arguments_length_offset = -1;
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < param_count; ++i) {
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame_offset -= kPointerSize;
1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, 0,
1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_frame_offset);
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!arg_count_known &&
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        descriptor.GetRegisterParameter(i)
1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            .is(descriptor.stack_parameter_count())) {
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arguments_length_offset = output_frame_offset;
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy constant stack parameters to the failure frame. If the number of stack
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // parameters is not known in the descriptor, the arguments object is the way
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to access them.
1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < stack_param_count; i++) {
1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame_offset -= kPointerSize;
1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object** stack_parameter = reinterpret_cast<Object**>(
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_ptr + StandardFrameConstants::kCallerSPOffset +
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (stack_param_count - i - 1) * kPointerSize);
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = reinterpret_cast<intptr_t>(*stack_parameter);
1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetFrameSlot(output_frame_offset, value);
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "stack parameter\n");
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_frame_offset);
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!arg_count_known) {
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_GE(arguments_length_offset, 0);
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We know it's a smi because 1) the code stub guarantees the stack
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // parameter count is in smi range, and 2) the DoTranslateCommand in the
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // parameter loop above translated that to a tagged value.
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Smi* smi_caller_arg_count = reinterpret_cast<Smi*>(
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        output_frame->GetFrameSlot(arguments_length_offset));
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    caller_arg_count = smi_caller_arg_count->value();
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetFrameSlot(length_frame_offset, caller_arg_count);
1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(caller_arg_count, frame_index, length_frame_offset,
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "args.length\n");
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (caller_arg_count - 1) * kPointerSize;
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetFrameSlot(args_arguments_offset, value);
1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, args_arguments_offset,
1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "args.arguments");
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy the double registers from the input into the output frame.
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CopyDoubleRegisters(output_frame);
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fill registers containing handler and number of parameters.
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetPlatformCompiledStubRegisters(output_frame, &descriptor);
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute this frame's PC, state, and continuation.
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* trampoline = NULL;
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StubFunctionMode function_mode = descriptor.function_mode();
1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StubFailureTrampolineStub(isolate_, function_mode)
1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      .FindCodeInCache(&trampoline);
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(trampoline != NULL);
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(reinterpret_cast<intptr_t>(
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      trampoline->instruction_start()));
1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register constant_pool_reg =
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        StubFailureTrampolineFrame::constant_pool_pointer_register();
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(trampoline->constant_pool());
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* notify_failure =
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles);
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetContinuation(
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<intptr_t>(notify_failure->entry()));
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_NE(DEBUGGER, bailout_type_);
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Walk to the last JavaScript output frame to find out if it has
1853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // adapted arguments.
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) {
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (frame_index != 0) it->Advance();
1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  translated_state_.Prepare(it->frame()->has_adapted_arguments(), stack_fp_);
1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& materialization : values_to_materialize_) {
1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> value = materialization.value_->GetValue();
1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (trace_scope_ != nullptr) {
1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF("Materialization [0x%08" V8PRIxPTR "] <- 0x%08" V8PRIxPTR " ;  ",
1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             reinterpret_cast<intptr_t>(materialization.output_slot_address_),
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             reinterpret_cast<intptr_t>(*value));
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value->ShortPrint(trace_scope_->file());
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF(trace_scope_->file(), "\n");
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *(reinterpret_cast<intptr_t*>(materialization.output_slot_address_)) =
1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<intptr_t>(*value);
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate_->materialized_object_store()->Remove(stack_fp_);
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1878f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochvoid Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
1879f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    int frame_index, int parameter_count, int expression_count,
1880f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    DeoptimizedFrameInfo* info) {
1881f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK_EQ(DEBUGGER, bailout_type_);
1882f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1883f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  translated_state_.Prepare(false, nullptr);
1884f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1885f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  TranslatedFrame* frame = &(translated_state_.frames()[frame_index]);
1886f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK(frame->kind() == TranslatedFrame::kFunction);
1887f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  int frame_arg_count = frame->shared_info()->internal_formal_parameter_count();
1888f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1889f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // The height is #expressions + 1 for context.
1890f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK_EQ(expression_count + 1, frame->height());
1891f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  TranslatedFrame* argument_frame = frame;
1892f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  if (frame_index > 0) {
1893f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    TranslatedFrame* previous_frame =
1894f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch        &(translated_state_.frames()[frame_index - 1]);
1895f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    if (previous_frame->kind() == TranslatedFrame::kArgumentsAdaptor) {
1896f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      argument_frame = previous_frame;
1897f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      CHECK_EQ(parameter_count, argument_frame->height() - 1);
1898f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    } else {
1899f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      CHECK_EQ(frame_arg_count, parameter_count);
1900f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    }
1901f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  } else {
1902f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    CHECK_EQ(frame_arg_count, parameter_count);
1903f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  }
1904f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1905f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  TranslatedFrame::iterator arg_iter = argument_frame->begin();
1906f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  arg_iter++;  // Skip the function.
1907f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  arg_iter++;  // Skip the receiver.
1908f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  for (int i = 0; i < parameter_count; i++, arg_iter++) {
1909f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    if (!arg_iter->IsMaterializedObject()) {
1910f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      info->SetParameter(i, *(arg_iter->GetValue()));
1911f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    }
1912f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  }
1913f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1914f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  TranslatedFrame::iterator iter = frame->begin();
1915f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Skip the function, receiver, context and arguments.
1916f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  for (int i = 0; i < frame_arg_count + 3; i++, iter++) {
1917f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  }
1918f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1919f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  for (int i = 0; i < expression_count; i++, iter++) {
1920f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    if (!iter->IsMaterializedObject()) {
1921f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      info->SetExpression(i, *(iter->GetValue()));
1922f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    }
1923f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  }
1924f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch}
1925f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1926f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::WriteTranslatedValueToOutput(
1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame::iterator* iterator, int* input_index, int frame_index,
1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned output_offset, const char* debug_hint_string,
1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address_for_materialization) {
1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* value = (*iterator)->GetRawValue();
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(value, *input_index, frame_index, output_offset,
1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     debug_hint_string);
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value == isolate_->heap()->arguments_marker()) {
1937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address =
1938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
1939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        output_offset;
1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output_address_for_materialization == nullptr) {
1941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_address_for_materialization = output_address;
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values_to_materialize_.push_back(
1944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        {output_address_for_materialization, *iterator});
1945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (*iterator)++;
1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (*input_index)++;
1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::WriteValueToOutput(Object* value, int input_index,
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     int frame_index, unsigned output_offset,
1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     const char* debug_hint_string) {
1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_[frame_index]->SetFrameSlot(output_offset,
1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     reinterpret_cast<intptr_t>(value));
1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(reinterpret_cast<intptr_t>(value), frame_index,
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         output_offset, debug_hint_string);
1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value->ShortPrint(trace_scope_->file());
1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "  (input #%d)\n", input_index);
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DebugPrintOutputSlot(intptr_t value, int frame_index,
1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       unsigned output_offset,
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       const char* debug_hint_string) {
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address =
1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        output_offset;
1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(),
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ;  %s",
1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           reinterpret_cast<intptr_t>(output_address), output_offset, value,
1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           debug_hint_string == nullptr ? "" : debug_hint_string);
1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochunsigned Deoptimizer::ComputeInputFrameSize() const {
1983f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned fixed_size = ComputeJavascriptFixedSize(function_);
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The fp-to-sp delta already takes the context, constant pool pointer and the
1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // function into account so we have to avoid double counting them.
1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned result = fixed_size + fp_to_sp_delta_ -
1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    StandardFrameConstants::kFixedFrameSizeFromFp;
1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned stack_slots = compiled_code_->stack_slots();
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned outgoing_size =
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ComputeOutgoingArgumentSize(compiled_code_, bailout_id_);
1992f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);
1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1997f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1998f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochunsigned Deoptimizer::ComputeJavascriptFixedSize(JSFunction* function) const {
1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The fixed part of the frame consists of the return address, frame
2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointer, function, context, and all the incoming arguments.
2001f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  return ComputeIncomingArgumentSize(function) +
2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         StandardFrameConstants::kFixedFrameSize;
2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2005f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2006f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochunsigned Deoptimizer::ComputeInterpretedFixedSize(JSFunction* function) const {
2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The fixed part of the frame consists of the return address, frame
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointer, function, context, new.target, bytecode offset and all the
2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // incoming arguments.
2010f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  return ComputeIncomingArgumentSize(function) +
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         InterpreterFrameConstants::kFixedFrameSize;
2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2014f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2015f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochunsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const {
2016f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // The incoming arguments is the values for formal parameters and
2017f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // the receiver. Every slot contains a pointer.
2018f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  if (function->IsSmi()) {
2019f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB));
2020f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    return 0;
2021f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  }
2022f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned arguments =
2023f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      function->shared()->internal_formal_parameter_count() + 1;
2024f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  return arguments * kPointerSize;
2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochunsigned Deoptimizer::ComputeOutgoingArgumentSize(Code* code,
2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                  unsigned bailout_id) {
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizationInputData* data =
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DeoptimizationInputData::cast(code->deoptimization_data());
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = data->ArgumentsStackHeight(bailout_id)->value();
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return height * kPointerSize;
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* Deoptimizer::ComputeLiteral(int index) const {
2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizationInputData* data =
2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DeoptimizationInputData::cast(compiled_code_->deoptimization_data());
2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* literals = data->LiteralArray();
2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return literals->get(index);
2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   BailoutType type,
2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   int max_entry_id) {
2049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We cannot run this if the serializer is enabled because this will
2050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // cause us to emit relocation information for the external
2051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // references. This is fine because the deoptimizer's code section
2052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // isn't meant to be serialized at all.
2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(type == EAGER || type == SOFT || type == LAZY);
2054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizerData* data = isolate->deoptimizer_data();
2055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int entry_count = data->deopt_entry_code_entries_[type];
2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (max_entry_id < entry_count) return;
2057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries);
2058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (max_entry_id >= entry_count) entry_count *= 2;
2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(entry_count <= Deoptimizer::kMaxNumberOfEntries);
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler masm(isolate, NULL, 16 * KB, CodeObjectRequired::kYes);
2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm.set_emit_debug_code(false);
2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenerateDeoptimizationEntries(&masm, entry_count, type);
2064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CodeDesc desc;
2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm.GetCode(&desc);
2066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!RelocInfo::RequiresRelocation(desc));
2067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MemoryChunk* chunk = data->deopt_entry_code_[type];
2069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        desc.instr_size);
2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!chunk->CommitArea(desc.instr_size)) {
2072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    V8::FatalProcessOutOfMemory(
2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        "Deoptimizer::EnsureCodeForDeoptimizationEntry");
2074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CopyBytes(chunk->area_start(), desc.buffer,
2076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            static_cast<size_t>(desc.instr_size));
2077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::FlushICache(isolate, chunk->area_start(), desc.instr_size);
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data->deopt_entry_code_entries_[type] = entry_count;
2080b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2081b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2082f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2083f2e3994fa5148cc3d9946666f0b0596290192b0eBen MurdochFrameDescription::FrameDescription(uint32_t frame_size,
2084f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                   JSFunction* function)
2085b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    : frame_size_(frame_size),
2086f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      function_(function),
2087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      top_(kZapUint32),
2088b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      pc_(kZapUint32),
20893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      fp_(kZapUint32),
2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      context_(kZapUint32),
2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      constant_pool_(kZapUint32) {
2092b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Zap all the registers.
2093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int r = 0; r < Register::kNumRegisters; r++) {
2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(jbramley): It isn't safe to use kZapUint32 here. If the register
2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // isn't used before the next safepoint, the GC will try to scan it as a
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // tagged value. kZapUint32 looks like a valid tagged pointer, but it isn't.
2097b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetRegister(r, kZapUint32);
2098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Zap all the slots.
2101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (unsigned o = 0; o < frame_size; o += kPointerSize) {
2102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFrameSlot(o, kZapUint32);
2103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
21073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint FrameDescription::ComputeFixedSize() {
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type_ == StackFrame::INTERPRETED) {
2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InterpreterFrameConstants::kFixedFrameSize +
2110f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch           (ComputeParametersCount() + 1) * kPointerSize;
2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return StandardFrameConstants::kFixedFrameSize +
2113f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch           (ComputeParametersCount() + 1) * kPointerSize;
2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
21153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
21163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochunsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) {
2119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (slot_index >= 0) {
2120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Local or spill slots. Skip the fixed part of the frame
2121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // including all arguments.
21223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    unsigned base = GetFrameSize() - ComputeFixedSize();
2123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return base - ((slot_index + 1) * kPointerSize);
2124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
2125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Incoming parameter.
2126f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    int arg_size = (ComputeParametersCount() + 1) * kPointerSize;
21273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    unsigned base = GetFrameSize() - arg_size;
2128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return base - ((slot_index + 1) * kPointerSize);
2129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2133f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochint FrameDescription::ComputeParametersCount() {
2134f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  switch (type_) {
2135f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    case StackFrame::JAVA_SCRIPT:
2136f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      return function_->shared()->internal_formal_parameter_count();
2137f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    case StackFrame::ARGUMENTS_ADAPTOR: {
2138f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      // Last slot contains number of incomming arguments as a smi.
2139f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      // Can't use GetExpression(0) because it would cause infinite recursion.
2140f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value();
2141f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    }
2142f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    case StackFrame::STUB:
2143f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      return -1;  // Minus receiver.
2144f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    default:
2145f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      FATAL("Unexpected stack frame type");
2146f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      return 0;
2147f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  }
2148f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch}
2149f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2150f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2151f2e3994fa5148cc3d9946666f0b0596290192b0eBen MurdochObject* FrameDescription::GetParameter(int index) {
2152f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK_GE(index, 0);
2153f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK_LT(index, ComputeParametersCount());
2154f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // The slot indexes for incoming arguments are negative.
2155f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount());
2156f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
2157f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch}
2158f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2159f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2160f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochunsigned FrameDescription::GetExpressionCount() {
2161f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  CHECK_EQ(StackFrame::JAVA_SCRIPT, type_);
2162f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned size = GetFrameSize() - ComputeFixedSize();
2163f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  return size / kPointerSize;
2164f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch}
2165f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2166f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2167f2e3994fa5148cc3d9946666f0b0596290192b0eBen MurdochObject* FrameDescription::GetExpression(int index) {
2168f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  DCHECK_EQ(StackFrame::JAVA_SCRIPT, type_);
2169f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  unsigned offset = GetOffsetFromSlotIndex(index);
2170f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
2171f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch}
2172f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2173f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TranslationBuffer::Add(int32_t value, Zone* zone) {
2175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This wouldn't handle kMinInt correctly if it ever encountered it.
2176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(value != kMinInt);
2177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Encode the sign bit in the least significant bit.
2178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_negative = (value < 0);
2179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t bits = ((is_negative ? -value : value) << 1) |
2180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<int32_t>(is_negative);
2181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Encode the individual bytes using the least significant bit of
2182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // each byte to indicate whether or not more bytes follow.
2183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  do {
2184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uint32_t next = bits >> 7;
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    contents_.Add(((bits << 1) & 0xFF) | (next != 0), zone);
2186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bits = next;
2187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } while (bits != 0);
2188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint32_t TranslationIterator::Next() {
2192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Run through the bytes until we reach one with a least significant
2193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // bit of zero (marks the end).
2194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t bits = 0;
2195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; true; i += 7) {
2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasNext());
2197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uint8_t next = buffer_->get(index_++);
2198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bits |= (next >> 1) << i;
2199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if ((next & 1) == 0) break;
2200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The bits encode the sign in the least significant bit.
2202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_negative = (bits & 1) == 1;
2203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t result = bits >> 1;
2204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return is_negative ? -result : result;
2205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) {
2209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = contents_.length();
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<ByteArray> result = factory->NewByteArray(length, TENURED);
2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemCopy(result->GetDataStartAddress(), contents_.ToVector().start(), length);
2212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
2213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
22163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Translation::BeginConstructStubFrame(int literal_id, unsigned height) {
2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(CONSTRUCT_STUB_FRAME, zone());
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(height, zone());
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginGetterStubFrame(int literal_id) {
2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(GETTER_STUB_FRAME, zone());
2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginSetterStubFrame(int literal_id) {
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(SETTER_STUB_FRAME, zone());
2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
22323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
22333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
22343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
22353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) {
2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone());
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(height, zone());
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginJSFrame(BailoutId node_id,
2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int literal_id,
2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               unsigned height) {
2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(JS_FRAME, zone());
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(node_id.ToInt(), zone());
2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(height, zone());
2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::BeginInterpretedFrame(BailoutId bytecode_offset,
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        int literal_id, unsigned height) {
2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(INTERPRETED_FRAME, zone());
2255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(bytecode_offset.ToInt(), zone());
2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(literal_id, zone());
2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(height, zone());
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::BeginCompiledStubFrame(int height) {
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(COMPILED_STUB_FRAME, zone());
2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(height, zone());
2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginArgumentsObject(int args_length) {
2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(ARGUMENTS_OBJECT, zone());
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(args_length, zone());
22703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
22713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
22723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginCapturedObject(int length) {
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(CAPTURED_OBJECT, zone());
2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(length, zone());
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::DuplicateObject(int object_index) {
2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(DUPLICATED_OBJECT, zone());
2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(object_index, zone());
2282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreRegister(Register reg) {
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(REGISTER, zone());
2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(reg.code(), zone());
2288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32Register(Register reg) {
2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(INT32_REGISTER, zone());
2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(reg.code(), zone());
2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreUint32Register(Register reg) {
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(UINT32_REGISTER, zone());
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(reg.code(), zone());
2300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::StoreBoolRegister(Register reg) {
2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(BOOL_REGISTER, zone());
2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(reg.code(), zone());
2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreDoubleRegister(DoubleRegister reg) {
2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(DOUBLE_REGISTER, zone());
2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(reg.code(), zone());
2312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreStackSlot(int index) {
2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(STACK_SLOT, zone());
2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(index, zone());
2318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32StackSlot(int index) {
2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(INT32_STACK_SLOT, zone());
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(index, zone());
2324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreUint32StackSlot(int index) {
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(UINT32_STACK_SLOT, zone());
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(index, zone());
2330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::StoreBoolStackSlot(int index) {
2334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(BOOL_STACK_SLOT, zone());
2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(index, zone());
2336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreDoubleStackSlot(int index) {
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(DOUBLE_STACK_SLOT, zone());
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(index, zone());
2342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreLiteral(int literal_id) {
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(LITERAL, zone());
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreArgumentsObject(bool args_known,
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       int args_index,
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       int args_length) {
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(ARGUMENTS_OBJECT, zone());
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(args_known, zone());
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(args_index, zone());
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(args_length, zone());
2358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::StoreJSFrameFunction() {
2362f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  buffer_->Add(JS_FRAME_FUNCTION, zone());
2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2365f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
2366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint Translation::NumberOfOperandsFor(Opcode opcode) {
2367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  switch (opcode) {
2368f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    case JS_FRAME_FUNCTION:
2369f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      return 0;
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case GETTER_STUB_FRAME:
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SETTER_STUB_FRAME:
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DUPLICATED_OBJECT:
2373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case ARGUMENTS_OBJECT:
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CAPTURED_OBJECT:
2375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case REGISTER:
2376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_REGISTER:
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case UINT32_REGISTER:
2378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BOOL_REGISTER:
2379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_REGISTER:
2380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case STACK_SLOT:
2381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_STACK_SLOT:
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case UINT32_STACK_SLOT:
2383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BOOL_STACK_SLOT:
2384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_STACK_SLOT:
2385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case LITERAL:
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case COMPILED_STUB_FRAME:
2387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return 1;
23883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case BEGIN:
23893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case ARGUMENTS_ADAPTOR_FRAME:
23903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case CONSTRUCT_STUB_FRAME:
23913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return 2;
23923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case JS_FRAME:
2393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case INTERPRETED_FRAME:
2394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return 3;
2395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FATAL("Unexpected translation type");
2397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* Translation::StringFor(Opcode opcode) {
2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define TRANSLATION_OPCODE_CASE(item)   case item: return #item;
2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (opcode) {
2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRANSLATION_OPCODE_LIST(TRANSLATION_OPCODE_CASE)
2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef TRANSLATION_OPCODE_CASE
2409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
2410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return "";
2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<FixedArray> MaterializedObjectStore::Get(Address fp) {
2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = StackIdToIndex(fp);
2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index == -1) {
2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Handle<FixedArray>::null();
2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> array = GetStackEntries();
2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_GT(array->length(), index);
2423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<FixedArray>::cast(Handle<Object>(array->get(index), isolate()));
2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MaterializedObjectStore::Set(Address fp,
2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  Handle<FixedArray> materialized_objects) {
2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = StackIdToIndex(fp);
2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index == -1) {
2431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    index = frame_fps_.length();
2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frame_fps_.Add(fp);
2433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> array = EnsureStackEntries(index + 1);
2436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array->set(index, *materialized_objects);
2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool MaterializedObjectStore::Remove(Address fp) {
2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = StackIdToIndex(fp);
2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index == -1) {
2443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
2444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_GE(index, 0);
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame_fps_.Remove(index);
2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* array = isolate()->heap()->materialized_objects();
2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_LT(index, array->length());
2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = index; i < frame_fps_.length(); i++) {
2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    array->set(i, array->get(i + 1));
2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array->set(frame_fps_.length(), isolate()->heap()->undefined_value());
2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint MaterializedObjectStore::StackIdToIndex(Address fp) {
2459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < frame_fps_.length(); i++) {
2460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (frame_fps_[i] == fp) {
2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return i;
2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
2465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<FixedArray> MaterializedObjectStore::GetStackEntries() {
2469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<FixedArray>(isolate()->heap()->materialized_objects());
2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<FixedArray> MaterializedObjectStore::EnsureStackEntries(int length) {
2474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> array = GetStackEntries();
2475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (array->length() >= length) {
2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return array;
2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_length = length > 10 ? length : 10;
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_length < 2 * array->length()) {
2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_length = 2 * array->length();
2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> new_array =
2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->factory()->NewFixedArray(new_length, TENURED);
2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < array->length(); i++) {
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_array->set(i, array->get(i));
2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = array->length(); i < length; i++) {
2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_array->set(i, isolate()->heap()->undefined_value());
2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate()->heap()->SetRootMaterializedObjects(*new_array);
2493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new_array;
2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2497f2e3994fa5148cc3d9946666f0b0596290192b0eBen MurdochDeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
2498f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                           int frame_index,
2499f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                           bool has_arguments_adaptor,
2500f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch                                           bool has_construct_stub) {
2501f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  FrameDescription* output_frame = deoptimizer->output_[frame_index];
2502f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  function_ = output_frame->GetFunction();
2503f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  context_ = reinterpret_cast<Object*>(output_frame->GetContext());
2504f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  has_construct_stub_ = has_construct_stub;
2505f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  expression_count_ = output_frame->GetExpressionCount();
2506f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  expression_stack_ = new Object* [expression_count_];
2507f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  // Get the source position using the unoptimized code.
2508f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Address pc = reinterpret_cast<Address>(output_frame->GetPc());
2509f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  Code* code = Code::cast(deoptimizer->isolate()->FindCodeObject(pc));
2510f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  source_position_ = code->SourcePosition(pc);
2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2512f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  for (int i = 0; i < expression_count_; i++) {
2513f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    Object* value = output_frame->GetExpression(i);
2514f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    // Replace materialization markers with the undefined value.
2515f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    if (value == deoptimizer->isolate()->heap()->arguments_marker()) {
2516f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      value = deoptimizer->isolate()->heap()->undefined_value();
2517f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    }
2518f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    SetExpression(i, value);
2519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
25208389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2521f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  if (has_arguments_adaptor) {
2522f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    output_frame = deoptimizer->output_[frame_index - 1];
2523f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    CHECK_EQ(output_frame->GetFrameType(), StackFrame::ARGUMENTS_ADAPTOR);
25248389745919cae02139ddc085a63c00d024269cf2Ben Murdoch  }
25258389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2526f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  parameters_count_ = output_frame->ComputeParametersCount();
2527f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  parameters_ = new Object* [parameters_count_];
2528f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  for (int i = 0; i < parameters_count_; i++) {
2529f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    Object* value = output_frame->GetParameter(i);
2530f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    // Replace materialization markers with the undefined value.
2531f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    if (value == deoptimizer->isolate()->heap()->arguments_marker()) {
2532f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      value = deoptimizer->isolate()->heap()->undefined_value();
2533f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    }
2534f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    SetParameter(i, value);
25358389745919cae02139ddc085a63c00d024269cf2Ben Murdoch  }
2536f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch}
25378389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
25388389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2539f2e3994fa5148cc3d9946666f0b0596290192b0eBen MurdochDeoptimizedFrameInfo::~DeoptimizedFrameInfo() {
2540f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  delete[] expression_stack_;
2541f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  delete[] parameters_;
2542f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch}
2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2545f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochvoid DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
2546f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  v->VisitPointer(bit_cast<Object**>(&function_));
2547f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  v->VisitPointer(&context_);
2548f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  v->VisitPointers(parameters_, parameters_ + parameters_count_);
2549f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) {
2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(deopt_reason < kLastDeoptReason);
2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DEOPT_MESSAGES_TEXTS(C, T) T,
2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const char* deopt_messages_[] = {
2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)};
2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DEOPT_MESSAGES_TEXTS
2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return deopt_messages_[deopt_reason];
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDeoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, Address pc) {
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePosition last_position = SourcePosition::Unknown();
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Deoptimizer::DeoptReason last_reason = Deoptimizer::kNoReason;
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int mask = RelocInfo::ModeMask(RelocInfo::DEOPT_REASON) |
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             RelocInfo::ModeMask(RelocInfo::POSITION);
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (RelocIterator it(code, mask); !it.done(); it.next()) {
2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RelocInfo* info = it.rinfo();
2570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (info->pc() >= pc) return DeoptInfo(last_position, NULL, last_reason);
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (info->rmode() == RelocInfo::POSITION) {
2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int raw_position = static_cast<int>(info->data());
2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_position = raw_position ? SourcePosition::FromRaw(raw_position)
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   : SourcePosition::Unknown();
2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (info->rmode() == RelocInfo::DEOPT_REASON) {
2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_reason = static_cast<Deoptimizer::DeoptReason>(info->data());
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return DeoptInfo(SourcePosition::Unknown(), NULL, Deoptimizer::kNoReason);
2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container,
2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int length,
2586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int object_index) {
2587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kArgumentsObject);
2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.materialization_info_ = {object_index, length};
2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container,
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   int length,
2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   int object_index) {
2597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kCapturedObject);
2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.materialization_info_ = {object_index, length};
2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewDuplicateObject(TranslatedState* container,
2605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int id) {
2606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kDuplicatedObject);
2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.materialization_info_ = {id, -1};
2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewDouble(TranslatedState* container,
2614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           double value) {
2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kDouble);
2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.double_value_ = value;
2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewInt32(TranslatedState* container,
2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          int32_t value) {
2624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kInt32);
2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.int32_value_ = value;
2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewUInt32(TranslatedState* container,
2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           uint32_t value) {
2633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kUInt32);
2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.uint32_value_ = value;
2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewBool(TranslatedState* container,
2641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         uint32_t value) {
2642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kBoolBit);
2643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.uint32_value_ = value;
2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewTagged(TranslatedState* container,
2650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           Object* literal) {
2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kTagged);
2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.raw_literal_ = literal;
2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewInvalid(TranslatedState* container) {
2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedValue(container, kInvalid);
2660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochIsolate* TranslatedValue::isolate() const { return container_->isolate(); }
2664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* TranslatedValue::raw_literal() const {
2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kTagged, kind());
2668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return raw_literal_;
2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint32_t TranslatedValue::int32_value() const {
2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kInt32, kind());
2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return int32_value_;
2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochuint32_t TranslatedValue::uint32_value() const {
2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind() == kUInt32 || kind() == kBoolBit);
2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return uint32_value_;
2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble TranslatedValue::double_value() const {
2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kDouble, kind());
2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return double_value_;
2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedValue::object_length() const {
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind() == kArgumentsObject || kind() == kCapturedObject);
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return materialization_info_.length_;
2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedValue::object_index() const {
2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind() == kArgumentsObject || kind() == kCapturedObject ||
2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         kind() == kDuplicatedObject);
2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return materialization_info_.id_;
2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* TranslatedValue::GetRawValue() const {
2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we have a value, return it.
2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> result_handle;
2706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value_.ToHandle(&result_handle)) {
2707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return *result_handle;
2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Otherwise, do a best effort to get the value without allocation.
2711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kTagged:
2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return raw_literal();
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInt32: {
2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_smi = Smi::IsValid(int32_value());
2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (is_smi) {
2718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Smi::FromInt(int32_value());
2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUInt32: {
2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_smi = (uint32_value() <= static_cast<uintptr_t>(Smi::kMaxValue));
2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (is_smi) {
2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Smi::FromInt(static_cast<int32_t>(uint32_value()));
2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kBoolBit: {
2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (uint32_value() == 0) {
2733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate()->heap()->false_value();
2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        CHECK_EQ(1U, uint32_value());
2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate()->heap()->true_value();
2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we could not get the value without allocation, return the arguments
2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // marker.
2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return isolate()->heap()->arguments_marker();
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> TranslatedValue::GetValue() {
2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> result;
2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we already have a value, then get it.
2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value_.ToHandle(&result)) return result;
2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Otherwise we have to materialize.
2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kTagged:
2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInt32:
2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kUInt32:
2760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kBoolBit:
2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDouble: {
2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MaterializeSimple();
2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return value_.ToHandleChecked();
2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kArgumentsObject:
2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kCapturedObject:
2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDuplicatedObject:
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return container_->MaterializeObjectAt(object_index());
2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInvalid:
2772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FATAL("unexpected case");
2773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Handle<Object>::null();
2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FATAL("internal error: value missing");
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<Object>::null();
2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedValue::MaterializeSimple() {
2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we already have materialized, return.
2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!value_.is_null()) return;
2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* raw_value = GetRawValue();
2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (raw_value != isolate()->heap()->arguments_marker()) {
2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We can get the value without allocation, just return it here.
2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ = Handle<Object>(raw_value, isolate());
2789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInt32: {
2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(int32_value()));
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUInt32:
2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(uint32_value()));
2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDouble:
2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(double_value()));
2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCapturedObject:
2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDuplicatedObject:
2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArgumentsObject:
2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInvalid:
2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kTagged:
2811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kBoolBit:
2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FATAL("internal error: unexpected materialization.");
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool TranslatedValue::IsMaterializedObject() const {
2819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCapturedObject:
2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDuplicatedObject:
2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArgumentsObject:
2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedValue::GetChildrenCount() const {
2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kind() == kCapturedObject || kind() == kArgumentsObject) {
2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return object_length();
2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return 0;
2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochuint32_t TranslatedState::GetUInt32Slot(Address fp, int slot_offset) {
2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address address = fp + slot_offset;
2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_BIG_ENDIAN && V8_HOST_ARCH_64_BIT
2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::uint32_at(address + kIntSize);
2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else
2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::uint32_at(address);
2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedValue::Handlify() {
2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kind() == kTagged) {
2851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ = Handle<Object>(raw_literal(), isolate());
2852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    raw_literal_ = nullptr;
2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id,
2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         SharedFunctionInfo* shared_info,
2859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         int height) {
2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info,
2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        height);
2862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame.node_id_ = node_id;
2863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return frame;
2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::InterpretedFrame(
2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BailoutId bytecode_offset, SharedFunctionInfo* shared_info, int height) {
2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame frame(kInterpretedFunction, shared_info->GetIsolate(),
2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        shared_info, height);
2871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame.node_id_ = bytecode_offset;
2872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return frame;
2873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::AccessorFrame(
2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Kind kind, SharedFunctionInfo* shared_info) {
2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind == kSetter || kind == kGetter);
2879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info);
2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame(
2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SharedFunctionInfo* shared_info, int height) {
2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(),
2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         shared_info, height);
2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::ConstructStubFrame(
2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SharedFunctionInfo* shared_info, int height) {
2892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info,
2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         height);
2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedFrame::GetValueCount() {
2898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFunction: {
2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int parameter_count =
2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          raw_shared_info_->internal_formal_parameter_count() + 1;
2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // + 1 for function.
2903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return height_ + parameter_count + 1;
2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInterpretedFunction: {
2907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int parameter_count =
2908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          raw_shared_info_->internal_formal_parameter_count() + 1;
2909f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      // + 3 for function, context and accumulator.
2910f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      return height_ + parameter_count + 3;
2911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kGetter:
2914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;  // Function and receiver.
2915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSetter:
2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 3;  // Function, receiver and the value to set.
2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArgumentsAdaptor:
2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kConstructStub:
2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 1 + height_;
2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCompiledStub:
2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return height_;
2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInvalid:
2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedFrame::Handlify() {
2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (raw_shared_info_ != nullptr) {
2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    shared_info_ = Handle<SharedFunctionInfo>(raw_shared_info_);
2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    raw_shared_info_ = nullptr;
2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& value : values_) {
2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value.Handlify();
2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedState::CreateNextTranslatedFrame(
2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslationIterator* iterator, FixedArray* literal_array, Address fp,
2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FILE* trace_file) {
2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode opcode =
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (opcode) {
2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::JS_FRAME: {
2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BailoutId node_id = BailoutId(iterator->Next());
2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading input frame %s", name.get());
2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int arg_count = shared_info->internal_formal_parameter_count() + 1;
2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n",
2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               node_id.ToInt(), arg_count, height);
2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::JSFrame(node_id, shared_info, height);
2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INTERPRETED_FRAME: {
2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BailoutId bytecode_offset = BailoutId(iterator->Next());
2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading input frame %s", name.get());
2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int arg_count = shared_info->internal_formal_parameter_count() + 1;
2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file,
2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               " => bytecode_offset=%d, args=%d, height=%d; inputs:\n",
2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               bytecode_offset.ToInt(), arg_count, height);
2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::InterpretedFrame(bytecode_offset, shared_info,
2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               height);
2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::ARGUMENTS_ADAPTOR_FRAME: {
2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading arguments adaptor frame %s", name.get());
2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, " => height=%d; inputs:\n", height);
2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height);
2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::CONSTRUCT_STUB_FRAME: {
3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading construct stub frame %s", name.get());
3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, " => height=%d; inputs:\n", height);
3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::ConstructStubFrame(shared_info, height);
3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::GETTER_STUB_FRAME: {
3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading getter frame %s; inputs:\n", name.get());
3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter,
3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            shared_info);
3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::SETTER_STUB_FRAME: {
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading setter frame %s; inputs:\n", name.get());
3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::AccessorFrame(TranslatedFrame::kSetter,
3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            shared_info);
3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::COMPILED_STUB_FRAME: {
3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file,
3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               "  reading compiler stub frame => height=%d; inputs:\n", height);
3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::CompiledStubFrame(height,
3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                literal_array->GetIsolate());
3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BEGIN:
3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DUPLICATED_OBJECT:
3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::ARGUMENTS_OBJECT:
3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::CAPTURED_OBJECT:
3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::REGISTER:
3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INT32_REGISTER:
3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::UINT32_REGISTER:
3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_REGISTER:
3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DOUBLE_REGISTER:
3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::STACK_SLOT:
3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INT32_STACK_SLOT:
3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::UINT32_STACK_SLOT:
3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_STACK_SLOT:
3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DOUBLE_STACK_SLOT:
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::LITERAL:
3061f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    case Translation::JS_FRAME_FUNCTION:
3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FATAL("We should never get here - unexpected deopt info.");
3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame::InvalidFrame();
3066b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
3067b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3068b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedFrame::AdvanceIterator(
3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    std::deque<TranslatedValue>::iterator* iter) {
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int values_to_skip = 1;
3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (values_to_skip > 0) {
3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Consume the current element.
3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values_to_skip--;
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Add all the children.
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values_to_skip += (*iter)->GetChildrenCount();
3078b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    (*iter)++;
3080b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3081b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
3082b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3083b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
30848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// We can't intermix stack decoding and allocations because
30858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// deoptimization infrastracture is not GC safe.
30868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Thus we build a temporary structure in malloced space.
3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedState::CreateNextTranslatedValue(
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int frame_index, int value_index, TranslationIterator* iterator,
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedArray* literal_array, Address fp, RegisterValues* registers,
3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FILE* trace_file) {
3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  disasm::NameConverter converter;
3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode opcode =
3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
30958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  switch (opcode) {
30968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::BEGIN:
30973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case Translation::JS_FRAME:
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INTERPRETED_FRAME:
30993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case Translation::ARGUMENTS_ADAPTOR_FRAME:
31003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case Translation::CONSTRUCT_STUB_FRAME:
3101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::GETTER_STUB_FRAME:
3102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::SETTER_STUB_FRAME:
3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::COMPILED_STUB_FRAME:
31048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      // Peeled off before getting here.
31058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      break;
31068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::DUPLICATED_OBJECT: {
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_id = iterator->Next();
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "duplicated object #%d", object_id);
3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_positions_.push_back(object_positions_[object_id]);
3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDuplicateObject(this, object_id);
3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::ARGUMENTS_OBJECT: {
3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int arg_count = iterator->Next();
3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_index = static_cast<int>(object_positions_.size());
3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "argumets object #%d (length = %d)", object_index,
3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               arg_count);
3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_positions_.push_back({frame_index, value_index});
3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewArgumentsObject(this, arg_count, object_index);
3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::CAPTURED_OBJECT: {
3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int field_count = iterator->Next();
3129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_index = static_cast<int>(object_positions_.size());
3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "captured object #%d (length = %d)", object_index,
3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               field_count);
3133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_positions_.push_back({frame_index, value_index});
3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDeferredObject(this, field_count,
3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                object_index);
3137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
31388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::REGISTER: {
3140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; %s ", value,
3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
3149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INT32_REGISTER: {
3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%" V8PRIdPTR " ; %s ", value,
3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewInt32(this, static_cast<int32_t>(value));
3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::UINT32_REGISTER: {
3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%" V8PRIuPTR " ; %s (uint)", value,
3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value));
3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_REGISTER: {
3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%" V8PRIdPTR " ; %s (bool)", value,
3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewBool(this, static_cast<uint32_t>(value));
3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DOUBLE_REGISTER: {
3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      double value = registers->GetDoubleRegister(input_reg);
3189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%e ; %s (bool)", value,
3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               DoubleRegister::from_code(input_reg).ToString());
3192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDouble(this, value);
3194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
31958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
31968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::STACK_SLOT: {
3197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset));
3200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; [fp %c %d] ", value,
3202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
32068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
32078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
32088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::INT32_STACK_SLOT: {
3209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t value = GetUInt32Slot(fp, slot_offset);
3212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%d ; (int) [fp %c %d] ",
3214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               static_cast<int32_t>(value), slot_offset < 0 ? '-' : '+',
3215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               std::abs(slot_offset));
3216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewInt32(this, value);
32188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
32198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::UINT32_STACK_SLOT: {
3221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t value = GetUInt32Slot(fp, slot_offset);
3224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value,
3226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewUInt32(this, value);
3229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_STACK_SLOT: {
3232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t value = GetUInt32Slot(fp, slot_offset);
3235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value,
3237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewBool(this, value);
3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
32428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::DOUBLE_STACK_SLOT: {
3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      double value = ReadDoubleValue(fp + slot_offset);
3246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%e ; (double) [fp %c %d] ", value,
3248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDouble(this, value);
32518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
32528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
32538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::LITERAL: {
32548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      int literal_index = iterator->Next();
3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Object* value = literal_array->get(literal_index);
3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ",
3258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               reinterpret_cast<intptr_t>(value), literal_index);
3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewTagged(this, value);
32638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
3264f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
3265f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    case Translation::JS_FRAME_FUNCTION: {
3266f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      int slot_offset = JavaScriptFrameConstants::kFunctionOffset;
3267f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset));
3268f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      if (trace_file != nullptr) {
3269f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; (frame function) ", value);
3270f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3271f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      }
3272f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
3273f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    }
32748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
32758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("We should never get here - unexpected deopt info.");
3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedValue(nullptr, TranslatedValue::kInvalid);
32788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
32798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
32808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedState::TranslatedState(JavaScriptFrame* frame)
3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : isolate_(nullptr),
3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      stack_frame_pointer_(nullptr),
3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_adapted_arguments_(false) {
3285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int deopt_index = Safepoint::kNoDeoptimizationIndex;
32868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  DeoptimizationInputData* data =
32878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
32888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  TranslationIterator it(data->TranslationByteArray(),
32898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                         data->TranslationIndex(deopt_index)->value());
3290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Init(frame->fp(), &it, data->LiteralArray(), nullptr /* registers */,
3291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       nullptr /* trace file */);
3292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedState::TranslatedState()
3296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : isolate_(nullptr),
3297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      stack_frame_pointer_(nullptr),
3298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_adapted_arguments_(false) {}
3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::Init(Address input_frame_pointer,
3302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           TranslationIterator* iterator,
3303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           FixedArray* literal_array, RegisterValues* registers,
3304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           FILE* trace_file) {
3305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(frames_.empty());
3306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate_ = literal_array->GetIsolate();
3308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read out the 'header' translation.
3309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode opcode =
3310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
3311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(opcode == Translation::BEGIN);
3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int count = iterator->Next();
3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  iterator->Next();  // Drop JS frames count.
3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frames_.reserve(count);
3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::stack<int> nested_counts;
3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read the frames
3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < count; i++) {
3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Read the frame descriptor.
3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frames_.push_back(CreateNextTranslatedFrame(
3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        iterator, literal_array, input_frame_pointer, trace_file));
3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame& frame = frames_.back();
3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Read the values.
3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int values_to_process = frame.GetValueCount();
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (values_to_process > 0 || !nested_counts.empty()) {
3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (nested_counts.empty()) {
3332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // For top level values, print the value number.
3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintF(trace_file, "    %3i: ",
3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 frame.GetValueCount() - values_to_process);
3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // Take care of indenting for nested values.
3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintF(trace_file, "         ");
3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          for (size_t j = 0; j < nested_counts.size(); j++) {
3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintF(trace_file, "  ");
3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedValue value = CreateNextTranslatedValue(
3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          i, static_cast<int>(frame.values_.size()), iterator, literal_array,
3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          input_frame_pointer, registers, trace_file);
3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame.Add(value);
3348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "\n");
3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
33523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Update the value count and resolve the nesting.
3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      values_to_process--;
3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int children_count = value.GetChildrenCount();
3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (children_count > 0) {
3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        nested_counts.push(values_to_process);
3358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        values_to_process = children_count;
3359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        while (values_to_process == 0 && !nested_counts.empty()) {
3361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          values_to_process = nested_counts.top();
3362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          nested_counts.pop();
3363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
33668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
3367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(!iterator->HasNext() ||
3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        static_cast<Translation::Opcode>(iterator->Next()) ==
3370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Translation::BEGIN);
3371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
33728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::Prepare(bool has_adapted_arguments,
3375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              Address stack_frame_pointer) {
3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& frame : frames_) frame.Handlify();
3377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  stack_frame_pointer_ = stack_frame_pointer;
3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  has_adapted_arguments_ = has_adapted_arguments;
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UpdateFromPreviouslyMaterializedObjects();
3382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> TranslatedState::MaterializeAt(int frame_index,
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              int* value_index) {
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* frame = &(frames_[frame_index]);
3388f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  DCHECK(static_cast<size_t>(*value_index) < frame->values_.size());
3389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue* slot = &(frame->values_[*value_index]);
3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (*value_index)++;
3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (slot->kind()) {
3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kTagged:
3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInt32:
3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kUInt32:
3397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kBoolBit:
3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDouble: {
3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot->MaterializeSimple();
3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> value = slot->GetValue();
3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (value->IsMutableHeapNumber()) {
3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        HeapNumber::cast(*value)->set_map(isolate()->heap()->heap_number_map());
3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return value;
3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kArgumentsObject: {
3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int length = slot->GetChildrenCount();
3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<JSObject> arguments;
3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (GetAdaptedArguments(&arguments, frame_index)) {
3411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Store the materialized object and consume the nested values.
3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (int i = 0; i < length; ++i) {
3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          MaterializeAt(frame_index, value_index);
3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSFunction> function =
3417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<JSFunction>::cast(frame->front().GetValue());
3418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        arguments = isolate_->factory()->NewArgumentsObject(function, length);
3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_EQ(array->length(), length);
3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        arguments->set_elements(*array);
3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (int i = 0; i < length; ++i) {
3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> value = MaterializeAt(frame_index, value_index);
3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          array->set(i, *value);
3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot->value_ = arguments;
3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return arguments;
3429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kCapturedObject: {
3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int length = slot->GetChildrenCount();
3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The map must be a tagged object.
3434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK(frame->values_[*value_index].kind() == TranslatedValue::kTagged);
3435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> result;
3437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (slot->value_.ToHandle(&result)) {
3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // This has been previously materialized, return the previous value.
3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // We still need to skip all the nested objects.
3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (int i = 0; i < length; i++) {
3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          MaterializeAt(frame_index, value_index);
3442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return result;
3445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> map_object = MaterializeAt(frame_index, value_index);
3448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Map> map =
3449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Map::GeneralizeAllFieldRepresentations(Handle<Map>::cast(map_object));
3450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      switch (map->instance_type()) {
3451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case MUTABLE_HEAP_NUMBER_TYPE:
3452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case HEAP_NUMBER_TYPE: {
3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Reuse the HeapNumber value directly as it is already properly
3454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // tagged and skip materializing the HeapNumber explicitly.
3455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> object = MaterializeAt(frame_index, value_index);
3456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // On 32-bit architectures, there is an extra slot there because
3458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // the escape analysis calculates the number of slots as
3459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // object-size/pointer-size. To account for this, we read out
3460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // any extra slots.
3461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          for (int i = 0; i < length - 2; i++) {
3462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            MaterializeAt(frame_index, value_index);
3463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
3464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return object;
3465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case JS_OBJECT_TYPE: {
3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Handle<JSObject> object =
3468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED);
3469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> properties = MaterializeAt(frame_index, value_index);
3471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> elements = MaterializeAt(frame_index, value_index);
3472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_properties(FixedArray::cast(*properties));
3473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_elements(FixedArrayBase::cast(*elements));
3474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          for (int i = 0; i < length - 3; ++i) {
3475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<Object> value = MaterializeAt(frame_index, value_index);
3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i);
3477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            object->FastPropertyAtPut(index, *value);
3478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return object;
3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case JS_ARRAY_TYPE: {
3482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Handle<JSArray> object =
3483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewJSArray(0, map->elements_kind());
3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> properties = MaterializeAt(frame_index, value_index);
3486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> elements = MaterializeAt(frame_index, value_index);
3487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> length = MaterializeAt(frame_index, value_index);
3488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_properties(FixedArray::cast(*properties));
3489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_elements(FixedArrayBase::cast(*elements));
3490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_length(*length);
3491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return object;
3492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case FIXED_ARRAY_TYPE: {
3494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> lengthObject = MaterializeAt(frame_index, value_index);
3495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int32_t length = 0;
3496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CHECK(lengthObject->ToInt32(&length));
3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<FixedArray> object =
3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewFixedArray(length);
3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // We need to set the map, because the fixed array we are
3500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // materializing could be a context or an arguments object,
3501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // in which case we must retain that information.
3502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          object->set_map(*map);
3503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          for (int i = 0; i < length; ++i) {
3505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<Object> value = MaterializeAt(frame_index, value_index);
3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            object->set(i, *value);
3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return object;
3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case FIXED_DOUBLE_ARRAY_TYPE: {
3511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map());
3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> lengthObject = MaterializeAt(frame_index, value_index);
3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int32_t length = 0;
3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CHECK(lengthObject->ToInt32(&length));
3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<FixedArrayBase> object =
3516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewFixedDoubleArray(length);
3517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (length > 0) {
3519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<FixedDoubleArray> double_array =
3520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                Handle<FixedDoubleArray>::cast(object);
3521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            for (int i = 0; i < length; ++i) {
3522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              Handle<Object> value = MaterializeAt(frame_index, value_index);
3523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              CHECK(value->IsNumber());
3524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              double_array->set(i, value->Number());
3525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
3526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return object;
3528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        default:
3530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintF(stderr, "[couldn't handle instance type %d]\n",
3531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 map->instance_type());
3532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          FATAL("unreachable");
3533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return Handle<Object>::null();
3534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDuplicatedObject: {
3540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_index = slot->object_index();
3541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedState::ObjectPosition pos = object_positions_[object_index];
3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Make sure the duplicate is refering to a previous object.
3544f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      DCHECK(pos.frame_index_ < frame_index ||
3545f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch             (pos.frame_index_ == frame_index &&
3546f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch              pos.value_index_ < *value_index - 1));
3547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> object =
3549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          frames_[pos.frame_index_].values_[pos.value_index_].GetValue();
3550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The object should have a (non-sentinel) value.
3552f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      DCHECK(!object.is_null() &&
3553f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch             !object.is_identical_to(isolate_->factory()->arguments_marker()));
3554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot->value_ = object;
3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return object;
3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInvalid:
3560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
3562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("We should never get here - unexpected deopt slot kind.");
3565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Object>::null();
3566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> TranslatedState::MaterializeObjectAt(int object_index) {
3570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedState::ObjectPosition pos = object_positions_[object_index];
3571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return MaterializeAt(pos.frame_index_, &(pos.value_index_));
3572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result,
3576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          int frame_index) {
3577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (frame_index == 0) {
3578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Top level frame -> we need to go to the parent frame on the stack.
3579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!has_adapted_arguments_) return false;
3580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This is top level frame, so we need to go to the stack to get
3582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // this function's argument. (Note that this relies on not inlining
3583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // recursive functions!)
3584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSFunction> function =
3585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSFunction>::cast(frames_[frame_index].front().GetValue());
3586f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    *result = Handle<JSObject>::cast(Accessors::FunctionGetArguments(function));
3587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame* previous_frame = &(frames_[frame_index]);
3590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (previous_frame->kind() != TranslatedFrame::kArgumentsAdaptor) {
3591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
3592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We get the adapted arguments from the parent translation.
3594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int length = previous_frame->height();
3595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSFunction> function =
3596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSFunction>::cast(previous_frame->front().GetValue());
3597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSObject> arguments =
3598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_->factory()->NewArgumentsObject(function, length);
3599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
3600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    arguments->set_elements(*array);
3601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame::iterator arg_iterator = previous_frame->begin();
3602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    arg_iterator++;  // Skip function.
3603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < length; ++i) {
3604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> value = arg_iterator->GetValue();
3605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array->set(i, *value);
3606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arg_iterator++;
3607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(arg_iterator == previous_frame->end());
3609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *result = arguments;
3610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex(
3616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int jsframe_index, int* args_count) {
3617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < frames_.size(); i++) {
3618f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    if (frames_[i].kind() == TranslatedFrame::kFunction) {
3619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (jsframe_index > 0) {
3620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        jsframe_index--;
3621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // We have the JS function frame, now check if it has arguments adaptor.
3623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (i > 0 &&
3624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            frames_[i - 1].kind() == TranslatedFrame::kArgumentsAdaptor) {
3625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          *args_count = frames_[i - 1].height();
3626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return &(frames_[i - 1]);
3627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        *args_count =
3629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            frames_[i].shared_info()->internal_formal_parameter_count() + 1;
3630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return &(frames_[i]);
3631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
3635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::StoreMaterializedValuesAndDeopt() {
3639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaterializedObjectStore* materialized_store =
3640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_->materialized_object_store();
3641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> previously_materialized_objects =
3642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      materialized_store->Get(stack_frame_pointer_);
3643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> marker = isolate_->factory()->arguments_marker();
3645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length = static_cast<int>(object_positions_.size());
3647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool new_store = false;
3648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (previously_materialized_objects.is_null()) {
3649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    previously_materialized_objects =
3650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_->factory()->NewFixedArray(length);
3651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < length; i++) {
3652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      previously_materialized_objects->set(i, *marker);
3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_store = true;
3655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3657f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  DCHECK_EQ(length, previously_materialized_objects->length());
3658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool value_changed = false;
3660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < length; i++) {
3661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedState::ObjectPosition pos = object_positions_[i];
3662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedValue* value_info =
3663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &(frames_[pos.frame_index_].values_[pos.value_index_]);
3664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3665f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    DCHECK(value_info->IsMaterializedObject());
3666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> value(value_info->GetRawValue(), isolate_);
3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!value.is_identical_to(marker)) {
3670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (previously_materialized_objects->get(i) == *marker) {
3671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        previously_materialized_objects->set(i, *value);
3672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value_changed = true;
3673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3674f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch        DCHECK(previously_materialized_objects->get(i) == *value);
3675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_store && value_changed) {
3679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    materialized_store->Set(stack_frame_pointer_,
3680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            previously_materialized_objects);
3681f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    DCHECK_EQ(TranslatedFrame::kFunction, frames_[0].kind());
3682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object* const function = frames_[0].front().GetRawValue();
3683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Deoptimizer::DeoptimizeFunction(JSFunction::cast(function));
3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
36858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
36868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
36878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::UpdateFromPreviouslyMaterializedObjects() {
3689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaterializedObjectStore* materialized_store =
3690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_->materialized_object_store();
3691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> previously_materialized_objects =
3692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      materialized_store->Get(stack_frame_pointer_);
36933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we have no previously materialized objects, there is nothing to do.
3695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (previously_materialized_objects.is_null()) return;
36963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> marker = isolate_->factory()->arguments_marker();
36983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length = static_cast<int>(object_positions_.size());
3700f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  DCHECK_EQ(length, previously_materialized_objects->length());
37013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < length; i++) {
3703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // For a previously materialized objects, inject their value into the
3704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // translated values.
3705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (previously_materialized_objects->get(i) != *marker) {
3706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedState::ObjectPosition pos = object_positions_[i];
3707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedValue* value_info =
3708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          &(frames_[pos.frame_index_].values_[pos.value_index_]);
3709f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      DCHECK(value_info->IsMaterializedObject());
37103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_info->value_ =
3712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object>(previously_materialized_objects->get(i), isolate_);
3713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
37153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
37163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
3718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
3719