deoptimizer.cc revision 109988c7ccb6f3fd1a58574fa3dfb88beaef6632
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"
14109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interpreter/interpreter.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h"
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/profiler/cpu-profiler.h"
17109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/tracing/trace-event.h"
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/v8.h"
19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 {
22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal {
23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic MemoryChunk* AllocateCodeChunk(MemoryAllocator* allocator) {
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return allocator->AllocateChunk(Deoptimizer::GetMaxDeoptTableSize(),
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  base::OS::CommitPageSize(),
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(__native_client__)
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The Native Client port of V8 uses an interpreter,
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // so code pages don't need PROT_EXEC.
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  NOT_EXECUTABLE,
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  EXECUTABLE,
333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  NULL);
3544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
37b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDeoptimizerData::DeoptimizerData(MemoryAllocator* allocator)
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : allocator_(allocator),
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      current_(NULL) {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < Deoptimizer::kBailoutTypesWithCodeEntry; ++i) {
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt_entry_code_entries_[i] = -1;
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt_entry_code_[i] = AllocateCodeChunk(allocator);
4444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDeoptimizerData::~DeoptimizerData() {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < Deoptimizer::kBailoutTypesWithCodeEntry; ++i) {
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocator_->Free(deopt_entry_code_[i]);
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt_entry_code_[i] = NULL;
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* Deoptimizer::FindDeoptimizingCode(Address addr) {
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (function_->IsHeapObject()) {
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Search all deoptimizing code in the native context of the function.
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = function_->context()->native_context();
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* element = native_context->DeoptimizedCodeListHead();
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (!element->IsUndefined()) {
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = Code::cast(element);
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (code->contains(addr)) return code;
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      element = code->next_code_link();
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// We rely on this function not causing a GC.  It is called from generated code
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// without having a real stack frame in place.
74b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer* Deoptimizer::New(JSFunction* function,
75b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              BailoutType type,
76b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              unsigned bailout_id,
77b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              Address from,
7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                              int fp_to_sp_delta,
7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                              Isolate* isolate) {
8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Deoptimizer* deoptimizer = new Deoptimizer(isolate,
8144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                             function,
8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                             type,
8344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                             bailout_id,
8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                             from,
853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                             fp_to_sp_delta,
863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                             NULL);
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(isolate->deoptimizer_data()->current_ == NULL);
8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->deoptimizer_data()->current_ = deoptimizer;
89b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return deoptimizer;
90b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
91b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// No larger than 2K on all platforms
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kDeoptTableMaxEpilogueCodeSize = 2 * KB;
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t Deoptimizer::GetMaxDeoptTableSize() {
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int entries_size =
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_;
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int commit_page_size = static_cast<int>(base::OS::CommitPageSize());
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) /
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    commit_page_size) + 1;
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<size_t>(commit_page_size * page_count);
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDeoptimizer* Deoptimizer::Grab(Isolate* isolate) {
10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Deoptimizer* result = isolate->deoptimizer_data()->current_;
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NOT_NULL(result);
110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  result->DeleteFrameDescriptions();
11144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->deoptimizer_data()->current_ = NULL;
112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) {
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (jsframe_index == 0) return 0;
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int frame_index = 0;
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (jsframe_index >= 0) {
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FrameDescription* frame = output_[frame_index];
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) {
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      jsframe_index--;
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    frame_index++;
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return frame_index - 1;
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochDeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    JavaScriptFrame* frame,
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int jsframe_index,
1353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    Isolate* isolate) {
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame->is_optimized());
137f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
138109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedState translated_values(frame);
139109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  translated_values.Prepare(false, frame->fp());
140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
141109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedState::iterator frame_it = translated_values.end();
142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int counter = jsframe_index;
143109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (auto it = translated_values.begin(); it != translated_values.end();
144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch       it++) {
145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (it->kind() == TranslatedFrame::kFunction ||
146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        it->kind() == TranslatedFrame::kInterpretedFunction) {
147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (counter == 0) {
148109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        frame_it = it;
149109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        break;
150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      counter--;
152109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK(frame_it != translated_values.end());
155f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DeoptimizedFrameInfo* info =
157109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new DeoptimizedFrameInfo(&translated_values, frame_it, isolate);
1583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return info;
1603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
1643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                 Isolate* isolate) {
1653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  delete info;
1663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                int count,
171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                BailoutType type) {
172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TableEntryGenerator generator(masm, type, count);
173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  generator.Generate();
174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::VisitAllOptimizedFunctionsForContext(
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* context, OptimizedFunctionVisitor* visitor) {
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(context->IsNativeContext());
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  visitor->EnterContext(context);
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit the list of optimized functions, removing elements that
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // no longer refer to optimized code.
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSFunction* prev = NULL;
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* element = context->OptimizedFunctionsListHead();
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!element->IsUndefined()) {
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    JSFunction* function = JSFunction::cast(element);
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* next = function->next_function_link();
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (function->code()->kind() != Code::OPTIMIZED_FUNCTION ||
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (visitor->VisitFunction(function),
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         function->code()->kind() != Code::OPTIMIZED_FUNCTION)) {
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The function no longer refers to optimized code, or the visitor
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // changed the code to which it refers to no longer be optimized code.
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Remove the function from this list.
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (prev != NULL) {
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        prev->set_next_function_link(next, UPDATE_WEAK_WRITE_BARRIER);
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        context->SetOptimizedFunctionsListHead(next);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The visitor should not alter the link directly.
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK_EQ(function->next_function_link(), next);
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Set the next function link to undefined to indicate it is no longer
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // in the optimized functions list.
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      function->set_next_function_link(context->GetHeap()->undefined_value(),
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       SKIP_WRITE_BARRIER);
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The visitor should not alter the link directly.
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK_EQ(function->next_function_link(), next);
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // preserve this element.
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      prev = function;
214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element = next;
216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  visitor->LeaveContext(context);
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::VisitAllOptimizedFunctions(
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    OptimizedFunctionVisitor* visitor) {
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Run through the list of all native contexts.
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!context->IsUndefined()) {
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor);
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Unlink functions referring to code marked for deoptimization, then move
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// marked code from the optimized code list to the deoptimized code list,
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and patch code for lazy deopt.
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) {
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A "closure" that unlinks optimized code that is going to be
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deoptimized from the functions that refer to it.
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class SelectedCodeUnlinker: public OptimizedFunctionVisitor {
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void EnterContext(Context* context) { }  // Don't care.
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void LeaveContext(Context* context)  { }  // Don't care.
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void VisitFunction(JSFunction* function) {
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = function->code();
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!code->marked_for_deoptimization()) return;
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Unlink this function and evict from optimized code map.
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SharedFunctionInfo* shared = function->shared();
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function->set_code(shared->code());
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_trace_deopt) {
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(), "[deoptimizer unlinked: ");
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        function->PrintName(scope.file());
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(),
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Unlink all functions that refer to marked code.
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SelectedCodeUnlinker unlinker;
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitAllOptimizedFunctionsForContext(context, &unlinker);
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate = context->GetHeap()->isolate();
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* topmost_optimized_code = NULL;
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool safe_to_deopt_topmost_optimized_code = false;
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Make sure all activations of optimized code can deopt at their current PC.
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The topmost optimized code has special handling because it cannot be
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deoptimized due to weak object dependency.
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (StackFrameIterator it(isolate, isolate->thread_local_top());
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       !it.done(); it.Advance()) {
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StackFrame::Type type = it.frame()->type();
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (type == StackFrame::OPTIMIZED) {
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = it.frame()->LookupCode();
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      JSFunction* function =
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<OptimizedFrame*>(it.frame())->function();
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_trace_deopt) {
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CodeTracer::Scope scope(isolate->GetCodeTracer());
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(), "[deoptimizer found activation of function: ");
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        function->PrintName(scope.file());
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(),
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SafepointEntry safepoint = code->GetSafepointEntry(it.frame()->pc());
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int deopt_index = safepoint.deoptimization_index();
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Turbofan deopt is checked when we are patching addresses on stack.
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool turbofanned = code->is_turbofanned() &&
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         function->shared()->asm_function() &&
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         !FLAG_turbo_asm_deoptimization;
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool safe_to_deopt =
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          deopt_index != Safepoint::kNoDeoptimizationIndex || turbofanned;
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(topmost_optimized_code == NULL || safe_to_deopt || turbofanned);
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (topmost_optimized_code == NULL) {
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        topmost_optimized_code = code;
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        safe_to_deopt_topmost_optimized_code = safe_to_deopt;
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Move marked code from the optimized code list to the deoptimized
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code list, collecting them into a ZoneList.
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone zone;
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Code*> codes(10, &zone);
312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Walk over all optimized code objects in this native context.
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* prev = NULL;
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* element = context->OptimizedCodeListHead();
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!element->IsUndefined()) {
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* code = Code::cast(element);
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* next = code->next_code_link();
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (code->marked_for_deoptimization()) {
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Put the code into the list for later patching.
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      codes.Add(code, &zone);
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (prev != NULL) {
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Skip this code in the optimized code list.
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        prev->set_next_code_link(next);
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // There was no previous node, the next node is the new head.
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        context->SetOptimizedCodeListHead(next);
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Move the code to the _deoptimized_ code list.
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code->set_next_code_link(context->DeoptimizedCodeListHead());
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      context->SetDeoptimizedCodeListHead(code);
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Not marked; preserve this element.
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      prev = code;
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element = next;
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
343109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // We need a handle scope only because of the macro assembler,
344109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // which is used in code patching in EnsureCodeForDeoptimizationEntry.
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate);
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Now patch all the codes for deoptimization.
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < codes.length(); i++) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (codes[i] == topmost_optimized_code) {
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(safe_to_deopt_topmost_optimized_code);
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // It is finally time to die, code object.
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Remove the code from optimized code map.
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizationInputData* deopt_data =
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DeoptimizationInputData::cast(codes[i]->deoptimization_data());
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SharedFunctionInfo* shared =
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo());
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    shared->EvictFromOptimizedCodeMap(codes[i], "deoptimized code");
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Do platform-specific patching to force any activations to lazy deopt.
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PatchCodeForDeoptimization(isolate, codes[i]);
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We might be in the middle of incremental marking with compaction.
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Tell collector to treat this code object in a special way and
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // ignore all slots that might have been recorded on it.
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]);
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeAll(Isolate* isolate) {
375109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE_EVENT0("v8", "V8.DeoptimizeCode");
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trace_deopt) {
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CodeTracer::Scope scope(isolate->GetCodeTracer());
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(scope.file(), "[deoptimize all code in all contexts]\n");
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For all contexts, mark all code, then deoptimize.
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!context->IsUndefined()) {
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = Context::cast(context);
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkAllCodeForContext(native_context);
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizeMarkedCodeForContext(native_context);
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    context = native_context->get(Context::NEXT_CONTEXT_LINK);
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) {
394109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
395109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE_EVENT0("v8", "V8.DeoptimizeCode");
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trace_deopt) {
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CodeTracer::Scope scope(isolate->GetCodeTracer());
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(scope.file(), "[deoptimize marked code in all contexts]\n");
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For all contexts, deoptimize code already marked.
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!context->IsUndefined()) {
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = Context::cast(context);
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizeMarkedCodeForContext(native_context);
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    context = native_context->get(Context::NEXT_CONTEXT_LINK);
407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::MarkAllCodeForContext(Context* context) {
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* element = context->OptimizedCodeListHead();
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!element->IsUndefined()) {
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* code = Code::cast(element);
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code->set_marked_for_deoptimization(true);
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element = code->next_code_link();
418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeFunction(JSFunction* function) {
423109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TimerEventScope<TimerEventDeoptimizeCode> timer(function->GetIsolate());
424109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE_EVENT0("v8", "V8.DeoptimizeCode");
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* code = function->code();
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (code->kind() == Code::OPTIMIZED_FUNCTION) {
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Mark the code for deoptimization and unlink any functions that also
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // refer to that code. The code cannot be shared across native contexts,
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // so we only need to search one.
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code->set_marked_for_deoptimization(true);
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizeMarkedCodeForContext(function->context()->native_context());
432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  deoptimizer->DoComputeOutputFrames();
438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Deoptimizer::TraceEnabledFor(BailoutType deopt_type,
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  StackFrame::Type frame_type) {
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (deopt_type) {
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EAGER:
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SOFT:
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LAZY:
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DEBUGGER:
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return (frame_type == StackFrame::STUB)
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ? FLAG_trace_stub_failures
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : FLAG_trace_deopt;
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("Unsupported deopt type");
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* Deoptimizer::MessageFor(BailoutType type) {
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (type) {
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EAGER: return "eager";
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SOFT: return "soft";
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LAZY: return "lazy";
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DEBUGGER: return "debugger";
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("Unsupported deopt type");
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDeoptimizer::Deoptimizer(Isolate* isolate, JSFunction* function,
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         BailoutType type, unsigned bailout_id, Address from,
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         int fp_to_sp_delta, Code* optimized_code)
47144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : isolate_(isolate),
47244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      function_(function),
473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bailout_id_(bailout_id),
474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bailout_type_(type),
475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      from_(from),
476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      fp_to_sp_delta_(fp_to_sp_delta),
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      has_alignment_padding_(0),
478109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      deoptimizing_throw_(false),
479109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      catch_handler_data_(-1),
480109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      catch_handler_pc_offset_(-1),
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      input_(nullptr),
482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_count_(0),
4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      jsframe_count_(0),
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_(nullptr),
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      trace_scope_(nullptr) {
486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (isolate->deoptimizer_lazy_throw()) {
487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    isolate->set_deoptimizer_lazy_throw(false);
488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    deoptimizing_throw_ = true;
489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For COMPILED_STUBs called from builtins, the function pointer is a SMI
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // indicating an internal frame.
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (function->IsSmi()) {
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    function = nullptr;
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(from != nullptr);
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (function != nullptr && function->IsOptimized()) {
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    function->shared()->increment_deopt_count();
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (bailout_type_ == Deoptimizer::SOFT) {
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->counters()->soft_deopts_executed()->Increment();
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Soft deopts shouldn't count against the overall re-optimization count
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // that can eventually lead to disabling optimization for a function.
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int opt_count = function->shared()->opt_count();
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (opt_count > 0) opt_count--;
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function->shared()->set_opt_count(opt_count);
5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compiled_code_ = FindOptimizedCode(function, optimized_code);
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if DEBUG
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(compiled_code_ != NULL);
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == EAGER || type == SOFT || type == LAZY) {
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(compiled_code_->kind() != Code::FUNCTION);
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackFrame::Type frame_type = function == NULL
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? StackFrame::STUB
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : StackFrame::JAVA_SCRIPT;
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  trace_scope_ = TraceEnabledFor(type, frame_type) ?
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL;
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(AllowHeapAllocation::IsAllowed());
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  disallow_heap_allocation_ = new DisallowHeapAllocation();
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PROFILE(isolate_, CodeDeoptEvent(compiled_code_, from_, fp_to_sp_delta_));
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned size = ComputeInputFrameSize();
529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count =
530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      function == nullptr
531109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          ? 0
532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          : (function->shared()->internal_formal_parameter_count() + 1);
533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  input_ = new (size) FrameDescription(size, parameter_count);
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_->SetFrameType(frame_type);
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* Deoptimizer::FindOptimizedCode(JSFunction* function,
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Code* optimized_code) {
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (bailout_type_) {
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Deoptimizer::SOFT:
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Deoptimizer::EAGER:
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Deoptimizer::LAZY: {
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* compiled_code = FindDeoptimizingCode(from_);
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return (compiled_code == NULL)
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ? static_cast<Code*>(isolate_->FindCodeObject(from_))
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : compiled_code;
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Deoptimizer::DEBUGGER:
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(optimized_code->contains(from_));
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return optimized_code;
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("Could not find code for optimized function");
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::PrintFunctionName() {
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (function_->IsJSFunction()) {
560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    function_->ShortPrint(trace_scope_->file());
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "%s", Code::Kind2String(compiled_code_->kind()));
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer::~Deoptimizer() {
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(input_ == NULL && output_ == NULL);
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(disallow_heap_allocation_ == NULL);
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete trace_scope_;
572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DeleteFrameDescriptions() {
576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete input_;
577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < output_count_; ++i) {
578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (output_[i] != input_) delete output_[i];
579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete[] output_;
581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  input_ = NULL;
582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  output_ = NULL;
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(!AllowHeapAllocation::IsAllowed());
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(disallow_heap_allocation_ != NULL);
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete disallow_heap_allocation_;
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  disallow_heap_allocation_ = NULL;
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            int id,
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            BailoutType type,
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            GetEntryMode mode) {
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_GE(id, 0);
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (id >= kMaxNumberOfEntries) return NULL;
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == ENSURE_ENTRY_CODE) {
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EnsureCodeForDeoptimizationEntry(isolate, type, id);
600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_EQ(mode, CALCULATE_ENTRY_ADDRESS);
602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeoptimizerData* data = isolate->deoptimizer_data();
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_LT(type, kBailoutTypesWithCodeEntry);
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* base = data->deopt_entry_code_[type];
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return base->area_start() + (id * table_entry_size_);
607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Deoptimizer::GetDeoptimizationId(Isolate* isolate,
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Address addr,
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     BailoutType type) {
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeoptimizerData* data = isolate->deoptimizer_data();
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* base = data->deopt_entry_code_[type];
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address start = base->area_start();
616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (addr < start ||
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addr >= start + (kMaxNumberOfEntries * table_entry_size_)) {
618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return kNotDeoptimizationEntry;
619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(0,
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            static_cast<int>(addr - start) % table_entry_size_);
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<int>(addr - start) / table_entry_size_;
623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6269fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockint Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               BailoutId id,
6289fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                               SharedFunctionInfo* shared) {
629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // TODO(kasperl): For now, we do a simple linear search for the PC
630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // offset associated with the given node id. This should probably be
631b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // changed to a binary search.
632b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = data->DeoptPoints();
633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < length; i++) {
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (data->AstId(i) == id) {
635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return data->PcAndState(i)->value();
636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OFStream os(stderr);
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os << "[couldn't find pc offset for node=" << id.ToInt() << "]\n"
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     << "[method: " << shared->DebugName()->ToCString().get() << "]\n"
641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier     << "[source:\n" << SourceCodeOf(shared) << "\n]" << std::endl;
642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  shared->GetHeap()->isolate()->PushStackTraceAndDie(0xfefefefe, data, shared,
644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                     0xfefefeff);
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("unable to find pc offset during deoptimization");
646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return -1;
647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
65044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) {
651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = 0;
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Count all entries in the deoptimizing code list of every context.
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!context->IsUndefined()) {
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = Context::cast(context);
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* element = native_context->DeoptimizedCodeListHead();
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (!element->IsUndefined()) {
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = Code::cast(element);
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      length++;
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      element = code->next_code_link();
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return length;
666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
668109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace {
669109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
670109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochint LookupCatchHandler(TranslatedFrame* translated_frame, int* data_out) {
671109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  switch (translated_frame->kind()) {
672109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case TranslatedFrame::kFunction: {
673109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      BailoutId node_id = translated_frame->node_id();
674109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      JSFunction* function =
675109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          JSFunction::cast(translated_frame->begin()->GetRawValue());
676109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Code* non_optimized_code = function->shared()->code();
677109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FixedArray* raw_data = non_optimized_code->deoptimization_data();
678109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
679109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      unsigned pc_and_state =
680109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          Deoptimizer::GetOutputInfo(data, node_id, function->shared());
681109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
682109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HandlerTable* table =
683109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          HandlerTable::cast(non_optimized_code->handler_table());
684109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HandlerTable::CatchPrediction prediction;
685109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return table->LookupRange(pc_offset, data_out, &prediction);
686109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
687109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case TranslatedFrame::kInterpretedFunction: {
688109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int bytecode_offset = translated_frame->node_id().ToInt();
689109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      JSFunction* function =
690109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          JSFunction::cast(translated_frame->begin()->GetRawValue());
691109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      BytecodeArray* bytecode = function->shared()->bytecode_array();
692109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HandlerTable* table = HandlerTable::cast(bytecode->handler_table());
693109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HandlerTable::CatchPrediction prediction;
694109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return table->LookupRange(bytecode_offset, data_out, &prediction);
695109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
696109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    default:
697109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
698109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
699109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return -1;
700109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
701109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
702109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}  // namespace
703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// We rely on this function not causing a GC.  It is called from generated code
7053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// without having a real stack frame in place.
706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DoComputeOutputFrames() {
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::ElapsedTimer timer;
708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Determine basic deoptimization information.  The optimized frame is
710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // described by the input data.
711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizationInputData* input_data =
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DeoptimizationInputData::cast(compiled_code_->deoptimization_data());
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    timer.Start();
716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ",
717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           MessageFor(bailout_type_));
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintFunctionName();
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           " (opt #%d) @%d, FP to SP delta: %d]\n",
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           input_data->OptimizationId()->value(),
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           bailout_id_,
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           fp_to_sp_delta_);
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (bailout_type_ == EAGER || bailout_type_ == SOFT ||
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (compiled_code_->is_hydrogen_stub())) {
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      compiled_code_->PrintDeoptLocation(trace_scope_->file(), from_);
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId node_id = input_data->AstId(bailout_id_);
731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ByteArray* translations = input_data->TranslationByteArray();
732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned translation_index =
733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      input_data->TranslationIndex(bailout_id_)->value();
734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslationIterator state_iterator(translations, translation_index);
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  translated_state_.Init(
737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      input_->GetFramePointerAddress(), &state_iterator,
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      input_data->LiteralArray(), input_->GetRegisterValues(),
739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      trace_scope_ == nullptr ? nullptr : trace_scope_->file());
740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Do the input frame to output frame(s) translation.
742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t count = translated_state_.frames().size();
743109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If we are supposed to go to the catch handler, find the catching frame
744109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // for the catch and make sure we only deoptimize upto that frame.
745109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (deoptimizing_throw_) {
746109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    size_t catch_handler_frame_index = count;
747109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (size_t i = count; i-- > 0;) {
748109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      catch_handler_pc_offset_ = LookupCatchHandler(
749109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          &(translated_state_.frames()[i]), &catch_handler_data_);
750109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (catch_handler_pc_offset_ >= 0) {
751109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        catch_handler_frame_index = i;
752109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        break;
753109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
754109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
755109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK_LT(catch_handler_frame_index, count);
756109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    count = catch_handler_frame_index + 1;
757109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
758109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(output_ == NULL);
760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  output_ = new FrameDescription*[count];
761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < count; ++i) {
762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    output_[i] = NULL;
763b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_count_ = static_cast<int>(count);
765b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register fp_reg = JavaScriptFrame::fp_register();
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stack_fp_ = reinterpret_cast<Address>(
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      input_->GetRegister(fp_reg.code()) +
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          has_alignment_padding_ * kPointerSize);
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Translate each output frame.
772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < count; ++i) {
7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Read the ast node id, function, and frame height for this output frame.
774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int frame_index = static_cast<int>(i);
775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (translated_state_.frames()[i].kind()) {
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kFunction:
777109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DoComputeJSFrame(frame_index, deoptimizing_throw_ && i == count - 1);
7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        jsframe_count_++;
7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kInterpretedFunction:
781109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DoComputeInterpretedFrame(frame_index,
782109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                  deoptimizing_throw_ && i == count - 1);
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        jsframe_count_++;
784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kArgumentsAdaptor:
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeArgumentsAdaptorFrame(frame_index);
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kConstructStub:
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeConstructStubFrame(frame_index);
7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kGetter:
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeAccessorStubFrame(frame_index, false);
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kSetter:
795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeAccessorStubFrame(frame_index, true);
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kCompiledStub:
798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DoComputeCompiledStubFrame(frame_index);
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kInvalid:
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FATAL("invalid frame");
8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
806b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Print some helpful diagnostic information.
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double ms = timer.Elapsed().InMillisecondsF();
809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int index = output_count_ - 1;  // Index of the topmost frame.
810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF(trace_scope_->file(), "[deoptimizing (%s): end ",
811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           MessageFor(bailout_type_));
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintFunctionName();
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           " took %0.3f ms]\n",
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           bailout_id_,
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           node_id.ToInt(),
818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           output_[index]->GetPc(),
819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           FullCodeGenerator::State2String(
820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               static_cast<FullCodeGenerator::State>(
821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                   output_[index]->GetState()->value())),
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           has_alignment_padding_ ? "with padding" : "no padding",
823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           ms);
824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
826b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
827109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
830109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  SharedFunctionInfo* shared = translated_frame->raw_shared_info();
831109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
833109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool is_bottommost = (0 == frame_index);
834109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool is_topmost = (output_count_ - 1 == frame_index);
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId node_id = translated_frame->node_id();
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height =
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translated_frame->height() - 1;  // Do not count the context.
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
841109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
842109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Take the stack height from the handler table.
843109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    height = catch_handler_data_;
844109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // We also make space for the exception itself.
845109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    height_in_bytes = (height + 1) * kPointerSize;
846109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK(is_topmost);
847109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "  translating frame ");
854109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    base::SmartArrayPointer<char> name = shared->DebugName()->ToCString();
855109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PrintF(trace_scope_->file(), "%s", name.get());
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
858109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(),
859109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           height_in_bytes, goto_catch_handler ? " (throw)" : "");
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The 'fixed' part of the frame consists of the incoming parameters and
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the part described by JavaScriptFrameConstants.
864109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared);
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned input_frame_size = input_->GetFrameSize();
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
869109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count = shared->internal_formal_parameter_count() + 1;
870109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FrameDescription* output_frame = new (output_frame_size)
871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FrameDescription(output_frame_size, parameter_count);
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame_index >= 0 && frame_index < output_count_);
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NULL(output_[frame_index]);
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address for the bottommost output frame can be computed from
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the input frame pointer and the output frame's height.  For all
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // subsequent output frames, it can be computed from the previous one's
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // top address and the current frame's size.
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register fp_reg = JavaScriptFrame::fp_register();
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address;
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_bottommost) {
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Determine whether the input frame contains alignment padding.
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_alignment_padding_ =
887109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        (!compiled_code_->is_turbofanned() && HasAlignmentPadding(shared)) ? 1
888109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                                                           : 0;
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // 2 = context and function in the frame.
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the optimized frame had alignment padding, adjust the frame pointer
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // to point to the new position of the old frame pointer after padding
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // is removed. Subtract 2 * kPointerSize for the context and function slots.
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    top_address = input_->GetRegister(fp_reg.code()) -
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        StandardFrameConstants::kFixedFrameSizeFromFp -
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        height_in_bytes + has_alignment_padding_ * kPointerSize;
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the incoming parameter translation.
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned input_offset = input_frame_size;
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= (parameter_count * kPointerSize);
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There are no translation commands for the caller's pc and fp, the
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // context, and the function.  Synthesize their values and set them up
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // explicitly.
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The caller's pc for the bottommost output frame is the same as in the
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // input frame.  For all subsequent output frames, it can be read from the
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // previous one.  This frame's pc can be computed from the non-optimized
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // function code and AST id of the bailout.
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= kPCOnStackSize;
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value;
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_bottommost) {
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = input_->GetFrameSlot(input_offset);
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetPc();
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, value);
928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The caller's frame pointer for the bottommost output frame is the same
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // as in the input frame.  For all subsequent output frames, it can be
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // read from the previous one.  Also compute and set this frame's frame
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // pointer.
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= kFPOnStackSize;
936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_bottommost) {
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = input_->GetFrameSlot(input_offset);
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetFp();
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!is_bottommost || (input_->GetRegister(fp_reg.code()) +
944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      has_alignment_padding_ * kPointerSize) == fp_value);
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!is_bottommost || !has_alignment_padding_ ||
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (fp_value & kPointerSize) != 0);
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // For the bottommost output frame the constant pool pointer can be gotten
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // from the input frame. For subsequent output frames, it can be read from
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the previous frame.
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    input_offset -= kPointerSize;
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_bottommost) {
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value = input_->GetFrameSlot(input_offset);
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value = output_[frame_index - 1]->GetConstantPool();
9618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For the bottommost output frame the context can be gotten from the input
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame. For all subsequent output frames it can be gotten from the function
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // so long as we don't inline functions that need local contexts.
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register context_reg = JavaScriptFrame::context_register();
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= kPointerSize;
973109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
974109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedFrame::iterator context_pos = value_iterator;
975109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int context_input_index = input_index;
976109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // When deoptimizing into a catch block, we need to take the context
977109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // from just above the top of the operand stack (we push the context
978109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // at the entry of the try block).
979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (unsigned i = 0; i < height + 1; ++i) {
981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      context_pos++;
982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      context_input_index++;
983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
984109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read the context from the translations.
986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Object* context = context_pos->GetRawValue();
987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (context == isolate_->heap()->undefined_value()) {
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the context was optimized away, just use the context from
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the activation. This should only apply to Crankshaft code.
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!compiled_code_->is_turbofanned());
991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    context =
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        is_bottommost
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ? reinterpret_cast<Object*>(input_->GetFrameSlot(input_offset))
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            : function->context();
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(context);
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetContext(value);
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_topmost) output_frame->SetRegister(context_reg.code(), value);
999109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteValueToOutput(context, context_input_index, frame_index, output_offset,
1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "context    ");
1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (context == isolate_->heap()->arguments_marker()) {
1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address =
1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        output_offset;
1005109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    values_to_materialize_.push_back({output_address, context_pos});
1006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The function was mentioned explicitly in the BEGIN_FRAME.
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_offset -= kPointerSize;
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(function);
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The function for the bottommost output frame should also agree with the
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // input frame.
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
1018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Translate the rest of the frame.
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (unsigned i = 0; i < height; ++i) {
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1025109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
1026109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Write out the exception for the catch handler.
1027109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    output_offset -= kPointerSize;
1028109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Object* exception_obj = reinterpret_cast<Object*>(
1029109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        input_->GetRegister(FullCodeGenerator::result_register().code()));
1030109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    WriteValueToOutput(exception_obj, input_index, frame_index, output_offset,
1031109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                       "exception   ");
1032109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    input_index++;
1033109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_offset);
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update constant pool.
1037109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Code* non_optimized_code = shared->code();
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(non_optimized_code->constant_pool());
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_topmost) {
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Register constant_pool_reg =
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          JavaScriptFrame::constant_pool_pointer_register();
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
10483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1049109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Compute this frame's PC, state, and continuation.
1050109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FixedArray* raw_data = non_optimized_code->deoptimization_data();
1051109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
1052109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Address start = non_optimized_code->instruction_start();
1053109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
1054109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned pc_offset = goto_catch_handler
1055109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           ? catch_handler_pc_offset_
1056109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           : FullCodeGenerator::PcField::decode(pc_and_state);
1057109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
1058109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_frame->SetPc(pc_value);
1059109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1060109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If we are going to the catch handler, then the exception lives in
1061109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // the accumulator.
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FullCodeGenerator::State state =
1063109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      goto_catch_handler ? FullCodeGenerator::TOS_REG
1064109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                         : FullCodeGenerator::StateField::decode(pc_and_state);
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetState(Smi::FromInt(state));
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set the continuation for the topmost frame.
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_topmost && bailout_type_ != DEBUGGER) {
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Builtins* builtins = isolate_->builtins();
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (bailout_type_ == LAZY) {
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (bailout_type_ == SOFT) {
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK_EQ(bailout_type_, EAGER);
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetContinuation(
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(continuation->entry()));
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
10823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1083109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid Deoptimizer::DoComputeInterpretedFrame(int frame_index,
1084109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                            bool goto_catch_handler) {
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1087109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  SharedFunctionInfo* shared = translated_frame->raw_shared_info();
1088109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1092109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int bytecode_offset = translated_frame->node_id().ToInt();
1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = translated_frame->height();
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height_in_bytes = height * kPointerSize;
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != NULL) {
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "  translating interpreted frame ");
1100109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    base::SmartArrayPointer<char> name = shared->DebugName()->ToCString();
1101109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PrintF(trace_scope_->file(), "%s", name.get());
1102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d%s\n",
1103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           bytecode_offset, height_in_bytes,
1104109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           goto_catch_handler ? " (throw)" : "");
1105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
1107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    bytecode_offset = catch_handler_pc_offset_;
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The 'fixed' part of the frame consists of the incoming parameters and
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the part described by InterpreterFrameConstants.
1112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared);
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned input_frame_size = input_->GetFrameSize();
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate and store the output frame description.
1117109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count = shared->internal_formal_parameter_count() + 1;
1118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FrameDescription* output_frame = new (output_frame_size)
1119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FrameDescription(output_frame_size, parameter_count);
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetFrameType(StackFrame::INTERPRETED);
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_bottommost = (0 == frame_index);
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_topmost = (output_count_ - 1 == frame_index);
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(frame_index >= 0 && frame_index < output_count_);
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NULL(output_[frame_index]);
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_[frame_index] = output_frame;
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The top address for the bottommost output frame can be computed from
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the input frame pointer and the output frame's height.  For all
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // subsequent output frames, it can be computed from the previous one's
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // top address and the current frame's size.
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register fp_reg = InterpretedFrame::fp_register();
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t top_address;
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_bottommost) {
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Subtract interpreter fixed frame size for the context function slots,
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // new,target and bytecode offset.
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    top_address = input_->GetRegister(fp_reg.code()) -
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  InterpreterFrameConstants::kFixedFrameSizeFromFp -
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  height_in_bytes;
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetTop(top_address);
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Compute the incoming parameter translation.
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned output_offset = output_frame_size;
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned input_offset = input_frame_size;
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < parameter_count; ++i) {
1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_offset -= kPointerSize;
1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= (parameter_count * kPointerSize);
1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // There are no translation commands for the caller's pc and fp, the
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // context, the function, new.target and the bytecode offset.  Synthesize
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // their values and set them up
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // explicitly.
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The caller's pc for the bottommost output frame is the same as in the
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // input frame.  For all subsequent output frames, it can be read from the
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // previous one.  This frame's pc can be computed from the non-optimized
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // function code and AST id of the bailout.
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPCOnStackSize;
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPCOnStackSize;
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t value;
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_bottommost) {
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = input_->GetFrameSlot(input_offset);
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = output_[frame_index - 1]->GetPc();
1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetCallerPc(output_offset, value);
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The caller's frame pointer for the bottommost output frame is the same
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // as in the input frame.  For all subsequent output frames, it can be
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // read from the previous one.  Also compute and set this frame's frame
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointer.
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kFPOnStackSize;
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kFPOnStackSize;
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_bottommost) {
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = input_->GetFrameSlot(input_offset);
1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = output_[frame_index - 1]->GetFp();
1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetCallerFp(output_offset, value);
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t fp_value = top_address + output_offset;
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!is_bottommost ||
1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         (input_->GetRegister(fp_reg.code()) +
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          has_alignment_padding_ * kPointerSize) == fp_value);
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetFp(fp_value);
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!is_bottommost || !has_alignment_padding_ ||
1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         (fp_value & kPointerSize) != 0);
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // For the bottommost output frame the constant pool pointer can be gotten
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // from the input frame. For subsequent output frames, it can be read from
1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // the previous frame.
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_offset -= kPointerSize;
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    input_offset -= kPointerSize;
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_bottommost) {
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value = input_->GetFrameSlot(input_offset);
1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value = output_[frame_index - 1]->GetConstantPool();
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // For the bottommost output frame the context can be gotten from the input
1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // frame. For all subsequent output frames it can be gotten from the function
1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // so long as we don't inline functions that need local contexts.
1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register context_reg = InterpretedFrame::context_register();
1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPointerSize;
1219109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1220109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // When deoptimizing into a catch block, we need to take the context
1221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // from a register that was specified in the handler table.
1222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedFrame::iterator context_pos = value_iterator;
1223109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int context_input_index = input_index;
1224109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
1225109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Skip to the translated value of the register specified
1226109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // in the handler table.
1227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (int i = 0; i < catch_handler_data_ + 1; ++i) {
1228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      context_pos++;
1229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      context_input_index++;
1230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read the context from the translations.
1233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Object* context = context_pos->GetRawValue();
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The context should not be a placeholder for a materialized object.
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(context != isolate_->heap()->arguments_marker());
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(context);
1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetContext(value);
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_topmost) output_frame->SetRegister(context_reg.code(), value);
1239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteValueToOutput(context, context_input_index, frame_index, output_offset,
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "context    ");
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The function was mentioned explicitly in the BEGIN_FRAME.
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPointerSize;
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(function);
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The function for the bottommost output frame should also agree with the
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // input frame.
1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // The new.target slot is only used during function activiation which is
1254109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // before the first deopt point, so should never be needed. Just set it to
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // undefined.
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPointerSize;
1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* new_target = isolate_->heap()->undefined_value();
1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target  ");
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1261109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Set the bytecode array pointer.
1262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_offset -= kPointerSize;
1263109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  input_offset -= kPointerSize;
1264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Object* bytecode_array = shared->bytecode_array();
1265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteValueToOutput(bytecode_array, 0, frame_index, output_offset,
1266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                     "bytecode array ");
1267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The bytecode offset was mentioned explicitly in the BEGIN_FRAME.
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_offset -= kPointerSize;
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int raw_bytecode_offset =
1272109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset;
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset);
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset,
1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "bytecode offset ");
1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Translate the rest of the interpreter registers in the frame.
1278109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (unsigned i = 0; i < height - 1; ++i) {
1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_offset -= kPointerSize;
1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1284109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Put the accumulator on the stack. It will be popped by the
1285109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // InterpreterNotifyDeopt builtin (possibly after materialization).
1286109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_offset -= kPointerSize;
1287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
1288109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // If we are lazy deopting to a catch handler, we set the accumulator to
1289109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // the exception (which lives in the result register).
1290109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    intptr_t accumulator_value =
1291109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        input_->GetRegister(FullCodeGenerator::result_register().code());
1292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0,
1293109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                       frame_index, output_offset, "accumulator ");
1294109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    value_iterator++;
1295109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
1296109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1297109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                 output_offset);
1298109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1299109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK_EQ(0u, output_offset);
1300f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Builtins* builtins = isolate_->builtins();
1302109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Code* dispatch_builtin =
1303109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
1304109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry()));
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetState(0);
1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Update constant pool.
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    intptr_t constant_pool_value =
1310109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool());
1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetConstantPool(constant_pool_value);
1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_topmost) {
1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register constant_pool_reg =
1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          InterpretedFrame::constant_pool_pointer_register();
1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Set the continuation for the topmost frame.
1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_topmost && bailout_type_ != DEBUGGER) {
1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Code* continuation =
1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        builtins->builtin(Builtins::kInterpreterNotifyDeoptimized);
1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (bailout_type_ == LAZY) {
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continuation =
1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          builtins->builtin(Builtins::kInterpreterNotifyLazyDeoptimized);
1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (bailout_type_ == SOFT) {
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continuation =
1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          builtins->builtin(Builtins::kInterpreterNotifySoftDeoptimized);
1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK_EQ(bailout_type_, EAGER);
1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetContinuation(
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<intptr_t>(continuation->entry()));
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) {
1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = translated_frame->height();
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating arguments adaptor => height=%d\n", height_in_bytes);
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
13533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
1358109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count = height;
1359109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FrameDescription* output_frame = new (output_frame_size)
1360109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FrameDescription(output_frame_size, parameter_count);
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Arguments adaptor can not be topmost or bottommost.
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame_index > 0 && frame_index < output_count_ - 1);
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(output_[frame_index] == NULL);
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address of the frame is computed from the previous
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame's top and this frame's size.
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address;
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the incoming parameter translation.
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
13813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC from the previous frame.
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, callers_pc);
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
13873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the previous frame, and set this frame's FP.
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = output_[frame_index - 1]->GetFp();
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the previous frame.
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetConstantPool();
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
14033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A marker value is used in place of the context.
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t context = reinterpret_cast<intptr_t>(
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, context);
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(context, frame_index, output_offset,
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "context (adaptor sentinel)\n");
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(function);
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of incoming arguments.
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "argc ");
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "(%d)\n", height - 1);
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(0 == output_offset);
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Builtins* builtins = isolate_->builtins();
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* adaptor_trampoline =
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc_value = reinterpret_cast<intptr_t>(
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      adaptor_trampoline->instruction_start() +
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(pc_value);
1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool());
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
14413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
14423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DoComputeConstructStubFrame(int frame_index) {
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Builtins* builtins = isolate_->builtins();
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
1452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = translated_frame->height();
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
1454109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Skip function.
1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating construct stub => height=%d\n", height_in_bytes);
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize;
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameDescription* output_frame =
1467109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (output_frame_size) FrameDescription(output_frame_size);
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::CONSTRUCT);
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Construct stub can not be topmost or bottommost.
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(frame_index > 0 && frame_index < output_count_ - 1);
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(output_[frame_index] == NULL);
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address of the frame is computed from the previous
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame's top and this frame's size.
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address;
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the incoming parameter translation.
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int parameter_count = height;
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The allocated receiver of a construct stub frame is passed as the
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // receiver parameter through the translation. It might be encoding
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // a captured object, override the slot address for a captured object.
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &value_iterator, &input_index, frame_index, output_offset, nullptr,
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (i == 0) ? reinterpret_cast<Address>(top_address) : nullptr);
1492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC from the previous frame.
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, callers_pc);
1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
1499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the previous frame, and set this frame's FP.
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = output_[frame_index - 1]->GetFp();
1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the previous frame.
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetConstantPool();
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The context can be gotten from the previous frame.
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = output_[frame_index - 1]->GetContext();
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A marker value is used in place of the function.
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset,
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "function (construct sentinel)\n");
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The output frame reflects a JSConstructStubGeneric frame.
1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(construct_stub);
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n");
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The allocation site.
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(isolate_->heap()->undefined_value());
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetFrameSlot(output_offset, value);
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "allocation site\n");
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of incoming arguments.
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "argc ");
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "(%d)\n", height - 1);
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The newly allocated object was passed as receiver in the artificial
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // constructor stub environment created by HEnvironment::CopyForInlining().
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset,
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "allocated receiver\n");
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_offset);
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc = reinterpret_cast<intptr_t>(
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      construct_stub->instruction_start() +
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->construct_stub_deopt_pc_offset()->value());
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(pc);
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(construct_stub->constant_pool());
1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DoComputeAccessorStubFrame(int frame_index,
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             bool is_setter_stub_frame) {
1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Skip accessor.
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The receiver (and the implicit return value, if any) are expected in
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // registers by the LoadIC/StoreIC, so they don't belong to the output stack
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame. This means that we have to use a height of 0.
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height = 0;
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* kind = is_setter_stub_frame ? "setter" : "getter";
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating %s stub => height=%u\n", kind, height_in_bytes);
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We need 1 stack entry for the return address and enough entries for the
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // StackFrame::INTERNAL (FP, context, frame type, code object and constant
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pool (if enabled)- see MacroAssembler::EnterFrame).
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For a setter stub frame we need one additional entry for the implicit
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // return value, see StoreStubCompiler::CompileStoreViaSetter.
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_entries =
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (StandardFrameConstants::kFixedFrameSize / kPointerSize) + 1 +
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (is_setter_stub_frame ? 1 : 0);
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameDescription* output_frame =
1607109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (output_frame_size) FrameDescription(output_frame_size);
1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::INTERNAL);
1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A frame for an accessor stub can not be the topmost or bottommost one.
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame_index > 0 && frame_index < output_count_ - 1);
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NULL(output_[frame_index]);
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address of the frame is computed from the previous frame's top and
1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // this frame's size.
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC from the previous frame.
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, callers_pc);
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the previous frame, and set this frame's FP.
1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = output_[frame_index - 1]->GetFp();
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the previous frame.
1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetConstantPool();
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The context can be gotten from the previous frame.
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = output_[frame_index - 1]->GetContext();
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A marker value is used in place of the function.
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "function ");
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "(%s sentinel)\n", kind);
1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get Code object from accessor stub.
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Builtins::Name name = is_setter_stub_frame ?
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Builtins::kStoreIC_Setter_ForDeopt :
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Builtins::kLoadIC_Getter_ForDeopt;
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* accessor_stub = isolate_->builtins()->builtin(name);
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(accessor_stub);
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n");
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Skip receiver.
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_setter_stub_frame) {
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The implicit return value was part of the artificial setter stub
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // environment.
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_offset);
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Smi* offset = is_setter_stub_frame ?
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->setter_stub_deopt_pc_offset() :
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->getter_stub_deopt_pc_offset();
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc = reinterpret_cast<intptr_t>(
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      accessor_stub->instruction_start() + offset->value());
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(pc);
1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DoComputeCompiledStubFrame(int frame_index) {
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //               FROM                                  TO
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |          ....           |          |          ....           |
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    +-------------------------+          +-------------------------+
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    | JSFunction continuation |          | JSFunction continuation |
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    +-------------------------+          +-------------------------+
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  |    saved frame (FP)     |          |    saved frame (FP)     |
1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  +=========================+<-fpreg   +=========================+<-fpreg
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  |constant pool (if ool_cp)|          |constant pool (if ool_cp)|
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  +-------------------------+          +-------------------------|
1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  |   JSFunction context    |          |   JSFunction context    |
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // v  +-------------------------+          +-------------------------|
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |   COMPILED_STUB marker  |          |   STUB_FAILURE marker   |
1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    +-------------------------+          +-------------------------+
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |                         |          |  caller args.arguments_ |
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    | ...                     |          +-------------------------+
1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |                         |          |  caller args.length_    |
1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |-------------------------|<-spreg   +-------------------------+
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         |  caller args pointer    |
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         +-------------------------+
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         |  caller stack param 1   |
1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //      parameters in registers            +-------------------------+
1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //       and spilled to stack              |           ....          |
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         +-------------------------+
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         |  caller stack param n   |
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         +-------------------------+<-spreg
1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = number of parameters
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = failure handler address
1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = saved frame
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = JSFunction context
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Caller stack params contain the register parameters to the stub first,
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // and then, if the descriptor specifies a constant number of stack
1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // parameters, the stack parameters as well.
1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* translated_frame =
1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      &(translated_state_.frames()[frame_index]);
1736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(compiled_code_->is_hydrogen_stub());
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int major_key = CodeStub::GetMajorKey(compiled_code_);
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeStubDescriptor descriptor(isolate_, compiled_code_->stub_key());
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The output frame must have room for all pushed register parameters
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and the standard stack frame slots.  Include space for an argument
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // object to the callee and optionally the space to pass the argument
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // object to the stub failure handler.
1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int param_count = descriptor.GetRegisterParameterCount();
1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int stack_param_count = descriptor.GetStackParameterCount();
1749109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // The translated frame contains all of the register parameters
1750109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // plus the context.
1751109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK_EQ(translated_frame->height(), param_count + 1);
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_GE(param_count, 0);
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int height_in_bytes = kPointerSize * (param_count + stack_param_count) +
1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        sizeof(Arguments) + kPointerSize;
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int input_frame_size = input_->GetFrameSize();
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int output_frame_size = height_in_bytes + fixed_frame_size;
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating %s => StubFailureTrampolineStub, height=%d\n",
1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           CodeStub::MajorName(static_cast<CodeStub::Major>(major_key)),
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           height_in_bytes);
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The stub failure trampoline is a single frame.
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameDescription* output_frame =
1768109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (output_frame_size) FrameDescription(output_frame_size);
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_EQ(frame_index, 0);
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address for the output frame can be computed from the input
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame pointer and the output frame's height. Subtract space for the
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // context and function slots.
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register fp_reg = StubFailureTrampolineFrame::fp_register();
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address = input_->GetRegister(fp_reg.code()) -
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes;
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC (JSFunction continuation) from the input frame.
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned input_frame_offset = input_frame_size - kPCOnStackSize;
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_offset = output_frame_size - kFPOnStackSize;
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = input_->GetFrameSlot(input_frame_offset);
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_frame_offset, value);
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "caller's pc\n");
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the input frame, and set this frame's FP.
1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_frame_offset -= kFPOnStackSize;
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = input_->GetFrameSlot(input_frame_offset);
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kFPOnStackSize;
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_frame_offset, value);
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t frame_ptr = input_->GetRegister(fp_reg.code());
1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetRegister(fp_reg.code(), frame_ptr);
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(frame_ptr);
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "caller's fp\n");
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the input frame.
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    input_frame_offset -= kPointerSize;
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = input_->GetFrameSlot(input_frame_offset);
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame_offset -= kPointerSize;
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_frame_offset, value);
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1810109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Remember where the context will need to be written back from the deopt
1811109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // translation.
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1813109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned context_frame_offset = output_frame_offset;
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A marker value is used in place of the function.
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE));
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_frame_offset, value);
1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "function (stub failure sentinel)\n");
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t caller_arg_count = stack_param_count;
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool arg_count_known = !descriptor.stack_parameter_count().is_valid();
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Build the Arguments object for the caller's parameters and a pointer to it.
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int args_arguments_offset = output_frame_offset;
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t the_hole = reinterpret_cast<intptr_t>(
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->the_hole_value());
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (arg_count_known) {
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (caller_arg_count - 1) * kPointerSize;
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = the_hole;
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(args_arguments_offset, value);
1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(
1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value, frame_index, args_arguments_offset,
1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arg_count_known ? "args.arguments\n" : "args.arguments (the hole)\n");
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int length_frame_offset = output_frame_offset;
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = arg_count_known ? caller_arg_count : the_hole;
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(length_frame_offset, value);
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(
1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value, frame_index, length_frame_offset,
1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arg_count_known ? "args.length\n" : "args.length (the hole)\n");
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = frame_ptr + StandardFrameConstants::kCallerSPOffset -
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (output_frame_size - output_frame_offset) + kPointerSize;
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_frame_offset, value);
1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset, "args*\n");
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy the register parameters to the failure frame.
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int arguments_length_offset = -1;
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < param_count; ++i) {
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame_offset -= kPointerSize;
1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, 0,
1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_frame_offset);
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!arg_count_known &&
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        descriptor.GetRegisterParameter(i)
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            .is(descriptor.stack_parameter_count())) {
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arguments_length_offset = output_frame_offset;
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Object* maybe_context = value_iterator->GetRawValue();
1872109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK(maybe_context->IsContext());
1873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Register context_reg = StubFailureTrampolineFrame::context_register();
1874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  value = reinterpret_cast<intptr_t>(maybe_context);
1875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_frame->SetRegister(context_reg.code(), value);
1876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_frame->SetFrameSlot(context_frame_offset, value);
1877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DebugPrintOutputSlot(value, frame_index, context_frame_offset, "context\n");
1878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ++value_iterator;
1879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy constant stack parameters to the failure frame. If the number of stack
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // parameters is not known in the descriptor, the arguments object is the way
1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to access them.
1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < stack_param_count; i++) {
1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame_offset -= kPointerSize;
1885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object** stack_parameter = reinterpret_cast<Object**>(
1886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_ptr + StandardFrameConstants::kCallerSPOffset +
1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (stack_param_count - i - 1) * kPointerSize);
1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = reinterpret_cast<intptr_t>(*stack_parameter);
1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetFrameSlot(output_frame_offset, value);
1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "stack parameter\n");
1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_frame_offset);
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!arg_count_known) {
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_GE(arguments_length_offset, 0);
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We know it's a smi because 1) the code stub guarantees the stack
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // parameter count is in smi range, and 2) the DoTranslateCommand in the
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // parameter loop above translated that to a tagged value.
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Smi* smi_caller_arg_count = reinterpret_cast<Smi*>(
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        output_frame->GetFrameSlot(arguments_length_offset));
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    caller_arg_count = smi_caller_arg_count->value();
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetFrameSlot(length_frame_offset, caller_arg_count);
1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(caller_arg_count, frame_index, length_frame_offset,
1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "args.length\n");
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (caller_arg_count - 1) * kPointerSize;
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetFrameSlot(args_arguments_offset, value);
1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, args_arguments_offset,
1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "args.arguments");
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy the double registers from the input into the output frame.
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CopyDoubleRegisters(output_frame);
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fill registers containing handler and number of parameters.
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetPlatformCompiledStubRegisters(output_frame, &descriptor);
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute this frame's PC, state, and continuation.
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* trampoline = NULL;
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StubFunctionMode function_mode = descriptor.function_mode();
1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StubFailureTrampolineStub(isolate_, function_mode)
1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      .FindCodeInCache(&trampoline);
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(trampoline != NULL);
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(reinterpret_cast<intptr_t>(
1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      trampoline->instruction_start()));
1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register constant_pool_reg =
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        StubFailureTrampolineFrame::constant_pool_pointer_register();
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(trampoline->constant_pool());
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* notify_failure =
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles);
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetContinuation(
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<intptr_t>(notify_failure->entry()));
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_NE(DEBUGGER, bailout_type_);
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Walk to the last JavaScript output frame to find out if it has
1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // adapted arguments.
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) {
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (frame_index != 0) it->Advance();
1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  translated_state_.Prepare(it->frame()->has_adapted_arguments(), stack_fp_);
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& materialization : values_to_materialize_) {
1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> value = materialization.value_->GetValue();
1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (trace_scope_ != nullptr) {
1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF("Materialization [0x%08" V8PRIxPTR "] <- 0x%08" V8PRIxPTR " ;  ",
1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             reinterpret_cast<intptr_t>(materialization.output_slot_address_),
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             reinterpret_cast<intptr_t>(*value));
1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value->ShortPrint(trace_scope_->file());
1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF(trace_scope_->file(), "\n");
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *(reinterpret_cast<intptr_t*>(materialization.output_slot_address_)) =
1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<intptr_t>(*value);
1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate_->materialized_object_store()->Remove(stack_fp_);
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::WriteTranslatedValueToOutput(
1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame::iterator* iterator, int* input_index, int frame_index,
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned output_offset, const char* debug_hint_string,
1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address_for_materialization) {
1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* value = (*iterator)->GetRawValue();
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(value, *input_index, frame_index, output_offset,
1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     debug_hint_string);
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value == isolate_->heap()->arguments_marker()) {
1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address =
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        output_offset;
1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output_address_for_materialization == nullptr) {
1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_address_for_materialization = output_address;
1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values_to_materialize_.push_back(
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        {output_address_for_materialization, *iterator});
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (*iterator)++;
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (*input_index)++;
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::WriteValueToOutput(Object* value, int input_index,
1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     int frame_index, unsigned output_offset,
2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     const char* debug_hint_string) {
2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_[frame_index]->SetFrameSlot(output_offset,
2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     reinterpret_cast<intptr_t>(value));
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(reinterpret_cast<intptr_t>(value), frame_index,
2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         output_offset, debug_hint_string);
2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value->ShortPrint(trace_scope_->file());
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "  (input #%d)\n", input_index);
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DebugPrintOutputSlot(intptr_t value, int frame_index,
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       unsigned output_offset,
2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       const char* debug_hint_string) {
2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address =
2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        output_offset;
2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(),
2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ;  %s",
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           reinterpret_cast<intptr_t>(output_address), output_offset, value,
2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           debug_hint_string == nullptr ? "" : debug_hint_string);
2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochunsigned Deoptimizer::ComputeInputFrameSize() const {
2029109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned fixed_size = StandardFrameConstants::kFixedFrameSize;
2030109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!function_->IsSmi()) {
2031109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    fixed_size += ComputeIncomingArgumentSize(function_->shared());
2032109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
2033109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK_EQ(Smi::cast(function_), Smi::FromInt(StackFrame::STUB));
2034109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The fp-to-sp delta already takes the context, constant pool pointer and the
2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // function into account so we have to avoid double counting them.
2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned result = fixed_size + fp_to_sp_delta_ -
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    StandardFrameConstants::kFixedFrameSizeFromFp;
2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned stack_slots = compiled_code_->stack_slots();
2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned outgoing_size =
2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ComputeOutgoingArgumentSize(compiled_code_, bailout_id_);
2043109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK(result ==
2044109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          fixed_size + (stack_slots * kPointerSize) -
2045109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              StandardFrameConstants::kFixedFrameSize + outgoing_size);
2046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2050109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// static
2051109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochunsigned Deoptimizer::ComputeJavascriptFixedSize(SharedFunctionInfo* shared) {
2052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The fixed part of the frame consists of the return address, frame
2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointer, function, context, and all the incoming arguments.
2054109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return ComputeIncomingArgumentSize(shared) +
2055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         StandardFrameConstants::kFixedFrameSize;
2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2058109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// static
2059109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochunsigned Deoptimizer::ComputeInterpretedFixedSize(SharedFunctionInfo* shared) {
2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The fixed part of the frame consists of the return address, frame
2061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointer, function, context, new.target, bytecode offset and all the
2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // incoming arguments.
2063109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return ComputeIncomingArgumentSize(shared) +
2064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         InterpreterFrameConstants::kFixedFrameSize;
2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2067109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// static
2068109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochunsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo* shared) {
2069109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return (shared->internal_formal_parameter_count() + 1) * kPointerSize;
2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2071b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochunsigned Deoptimizer::ComputeOutgoingArgumentSize(Code* code,
2075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                  unsigned bailout_id) {
2076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizationInputData* data =
2077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DeoptimizationInputData::cast(code->deoptimization_data());
2078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = data->ArgumentsStackHeight(bailout_id)->value();
2079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return height * kPointerSize;
2080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2082b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* Deoptimizer::ComputeLiteral(int index) const {
2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizationInputData* data =
2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DeoptimizationInputData::cast(compiled_code_->deoptimization_data());
2086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* literals = data->LiteralArray();
2087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return literals->get(index);
2088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2089b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2090b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   BailoutType type,
2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   int max_entry_id) {
2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We cannot run this if the serializer is enabled because this will
2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // cause us to emit relocation information for the external
2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // references. This is fine because the deoptimizer's code section
2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // isn't meant to be serialized at all.
2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(type == EAGER || type == SOFT || type == LAZY);
2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizerData* data = isolate->deoptimizer_data();
2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int entry_count = data->deopt_entry_code_entries_[type];
2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (max_entry_id < entry_count) return;
2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries);
2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (max_entry_id >= entry_count) entry_count *= 2;
2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(entry_count <= Deoptimizer::kMaxNumberOfEntries);
2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler masm(isolate, NULL, 16 * KB, CodeObjectRequired::kYes);
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm.set_emit_debug_code(false);
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenerateDeoptimizationEntries(&masm, entry_count, type);
2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CodeDesc desc;
2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm.GetCode(&desc);
2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!RelocInfo::RequiresRelocation(desc));
2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MemoryChunk* chunk = data->deopt_entry_code_[type];
2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        desc.instr_size);
2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!chunk->CommitArea(desc.instr_size)) {
2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    V8::FatalProcessOutOfMemory(
2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        "Deoptimizer::EnsureCodeForDeoptimizationEntry");
2119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CopyBytes(chunk->area_start(), desc.buffer,
2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            static_cast<size_t>(desc.instr_size));
2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::FlushICache(isolate, chunk->area_start(), desc.instr_size);
2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data->deopt_entry_code_entries_[type] = entry_count;
2125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochFrameDescription::FrameDescription(uint32_t frame_size, int parameter_count)
2128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    : frame_size_(frame_size),
2129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      parameter_count_(parameter_count),
2130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      top_(kZapUint32),
2131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      pc_(kZapUint32),
21323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      fp_(kZapUint32),
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      context_(kZapUint32),
2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      constant_pool_(kZapUint32) {
2135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Zap all the registers.
2136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int r = 0; r < Register::kNumRegisters; r++) {
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(jbramley): It isn't safe to use kZapUint32 here. If the register
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // isn't used before the next safepoint, the GC will try to scan it as a
2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // tagged value. kZapUint32 looks like a valid tagged pointer, but it isn't.
2140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetRegister(r, kZapUint32);
2141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Zap all the slots.
2144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (unsigned o = 0; o < frame_size; o += kPointerSize) {
2145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFrameSlot(o, kZapUint32);
2146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
21503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint FrameDescription::ComputeFixedSize() {
2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type_ == StackFrame::INTERPRETED) {
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InterpreterFrameConstants::kFixedFrameSize +
2153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           parameter_count() * kPointerSize;
2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return StandardFrameConstants::kFixedFrameSize +
2156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           parameter_count() * kPointerSize;
2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
21583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
21593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochunsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) {
2162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (slot_index >= 0) {
2163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Local or spill slots. Skip the fixed part of the frame
2164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // including all arguments.
21653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    unsigned base = GetFrameSize() - ComputeFixedSize();
2166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return base - ((slot_index + 1) * kPointerSize);
2167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
2168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Incoming parameter.
2169109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int arg_size = parameter_count() * kPointerSize;
21703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    unsigned base = GetFrameSize() - arg_size;
2171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return base - ((slot_index + 1) * kPointerSize);
2172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TranslationBuffer::Add(int32_t value, Zone* zone) {
2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This wouldn't handle kMinInt correctly if it ever encountered it.
2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(value != kMinInt);
2179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Encode the sign bit in the least significant bit.
2180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_negative = (value < 0);
2181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t bits = ((is_negative ? -value : value) << 1) |
2182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<int32_t>(is_negative);
2183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Encode the individual bytes using the least significant bit of
2184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // each byte to indicate whether or not more bytes follow.
2185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  do {
2186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uint32_t next = bits >> 7;
2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    contents_.Add(((bits << 1) & 0xFF) | (next != 0), zone);
2188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bits = next;
2189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } while (bits != 0);
2190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint32_t TranslationIterator::Next() {
2194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Run through the bytes until we reach one with a least significant
2195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // bit of zero (marks the end).
2196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t bits = 0;
2197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; true; i += 7) {
2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasNext());
2199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uint8_t next = buffer_->get(index_++);
2200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bits |= (next >> 1) << i;
2201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if ((next & 1) == 0) break;
2202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The bits encode the sign in the least significant bit.
2204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_negative = (bits & 1) == 1;
2205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t result = bits >> 1;
2206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return is_negative ? -result : result;
2207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) {
2211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = contents_.length();
2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<ByteArray> result = factory->NewByteArray(length, TENURED);
2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemCopy(result->GetDataStartAddress(), contents_.ToVector().start(), length);
2214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
2215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
22183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Translation::BeginConstructStubFrame(int literal_id, unsigned height) {
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(CONSTRUCT_STUB_FRAME, zone());
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(height, zone());
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginGetterStubFrame(int literal_id) {
2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(GETTER_STUB_FRAME, zone());
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginSetterStubFrame(int literal_id) {
2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(SETTER_STUB_FRAME, zone());
2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
22343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
22353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
22363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
22373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) {
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone());
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(height, zone());
2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginJSFrame(BailoutId node_id,
2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int literal_id,
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               unsigned height) {
2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(JS_FRAME, zone());
2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(node_id.ToInt(), zone());
2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(height, zone());
2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::BeginInterpretedFrame(BailoutId bytecode_offset,
2255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        int literal_id, unsigned height) {
2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(INTERPRETED_FRAME, zone());
2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(bytecode_offset.ToInt(), zone());
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(literal_id, zone());
2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(height, zone());
2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::BeginCompiledStubFrame(int height) {
2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(COMPILED_STUB_FRAME, zone());
2265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(height, zone());
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginArgumentsObject(int args_length) {
2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(ARGUMENTS_OBJECT, zone());
2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(args_length, zone());
22723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
22733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
22743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginCapturedObject(int length) {
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(CAPTURED_OBJECT, zone());
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(length, zone());
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::DuplicateObject(int object_index) {
2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(DUPLICATED_OBJECT, zone());
2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(object_index, zone());
2284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreRegister(Register reg) {
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(REGISTER, zone());
2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(reg.code(), zone());
2290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32Register(Register reg) {
2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(INT32_REGISTER, zone());
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(reg.code(), zone());
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreUint32Register(Register reg) {
2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(UINT32_REGISTER, zone());
2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(reg.code(), zone());
2302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::StoreBoolRegister(Register reg) {
2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(BOOL_REGISTER, zone());
2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(reg.code(), zone());
2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreDoubleRegister(DoubleRegister reg) {
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(DOUBLE_REGISTER, zone());
2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(reg.code(), zone());
2314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreStackSlot(int index) {
2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(STACK_SLOT, zone());
2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(index, zone());
2320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32StackSlot(int index) {
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(INT32_STACK_SLOT, zone());
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(index, zone());
2326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreUint32StackSlot(int index) {
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(UINT32_STACK_SLOT, zone());
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(index, zone());
2332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::StoreBoolStackSlot(int index) {
2336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(BOOL_STACK_SLOT, zone());
2337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  buffer_->Add(index, zone());
2338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreDoubleStackSlot(int index) {
2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(DOUBLE_STACK_SLOT, zone());
2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(index, zone());
2344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreLiteral(int literal_id) {
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(LITERAL, zone());
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(literal_id, zone());
2350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreArgumentsObject(bool args_known,
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       int args_index,
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       int args_length) {
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(ARGUMENTS_OBJECT, zone());
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(args_known, zone());
2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(args_index, zone());
2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_->Add(args_length, zone());
2360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::StoreJSFrameFunction() {
2364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  StoreStackSlot((StandardFrameConstants::kCallerPCOffset -
2365109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                  StandardFrameConstants::kMarkerOffset) /
2366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                 kPointerSize);
2367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint Translation::NumberOfOperandsFor(Opcode opcode) {
2370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  switch (opcode) {
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case GETTER_STUB_FRAME:
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SETTER_STUB_FRAME:
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DUPLICATED_OBJECT:
2374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case ARGUMENTS_OBJECT:
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CAPTURED_OBJECT:
2376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case REGISTER:
2377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_REGISTER:
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case UINT32_REGISTER:
2379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BOOL_REGISTER:
2380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_REGISTER:
2381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case STACK_SLOT:
2382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_STACK_SLOT:
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case UINT32_STACK_SLOT:
2384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BOOL_STACK_SLOT:
2385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_STACK_SLOT:
2386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case LITERAL:
2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case COMPILED_STUB_FRAME:
2388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return 1;
23893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case BEGIN:
23903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case ARGUMENTS_ADAPTOR_FRAME:
23913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case CONSTRUCT_STUB_FRAME:
23923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return 2;
23933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case JS_FRAME:
2394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case INTERPRETED_FRAME:
2395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return 3;
2396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FATAL("Unexpected translation type");
2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* Translation::StringFor(Opcode opcode) {
2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define TRANSLATION_OPCODE_CASE(item)   case item: return #item;
2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (opcode) {
2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRANSLATION_OPCODE_LIST(TRANSLATION_OPCODE_CASE)
2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef TRANSLATION_OPCODE_CASE
2410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return "";
2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<FixedArray> MaterializedObjectStore::Get(Address fp) {
2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = StackIdToIndex(fp);
2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index == -1) {
2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Handle<FixedArray>::null();
2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> array = GetStackEntries();
2423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_GT(array->length(), index);
2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<FixedArray>::cast(Handle<Object>(array->get(index), isolate()));
2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MaterializedObjectStore::Set(Address fp,
2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  Handle<FixedArray> materialized_objects) {
2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = StackIdToIndex(fp);
2431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index == -1) {
2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    index = frame_fps_.length();
2433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frame_fps_.Add(fp);
2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> array = EnsureStackEntries(index + 1);
2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array->set(index, *materialized_objects);
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool MaterializedObjectStore::Remove(Address fp) {
2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = StackIdToIndex(fp);
2443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index == -1) {
2444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
2445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_GE(index, 0);
2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame_fps_.Remove(index);
2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* array = isolate()->heap()->materialized_objects();
2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_LT(index, array->length());
2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = index; i < frame_fps_.length(); i++) {
2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    array->set(i, array->get(i + 1));
2453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array->set(frame_fps_.length(), isolate()->heap()->undefined_value());
2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
2456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint MaterializedObjectStore::StackIdToIndex(Address fp) {
2460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < frame_fps_.length(); i++) {
2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (frame_fps_[i] == fp) {
2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return i;
2463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<FixedArray> MaterializedObjectStore::GetStackEntries() {
2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<FixedArray>(isolate()->heap()->materialized_objects());
2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<FixedArray> MaterializedObjectStore::EnsureStackEntries(int length) {
2475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> array = GetStackEntries();
2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (array->length() >= length) {
2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return array;
2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_length = length > 10 ? length : 10;
2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_length < 2 * array->length()) {
2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_length = 2 * array->length();
2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> new_array =
2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->factory()->NewFixedArray(new_length, TENURED);
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < array->length(); i++) {
2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_array->set(i, array->get(i));
2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = array->length(); i < length; i++) {
2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_array->set(i, isolate()->heap()->undefined_value());
2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate()->heap()->SetRootMaterializedObjects(*new_array);
2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new_array;
2495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace {
2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochHandle<Object> GetValueForDebugger(TranslatedFrame::iterator it,
2500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                   Isolate* isolate) {
2501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (it->GetRawValue() == isolate->heap()->arguments_marker()) {
2502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!it->IsMaterializableByDebugger()) {
2503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return isolate->factory()->undefined_value();
2504f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    }
2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return it->GetValue();
2507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
25088389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochint ComputeSourcePosition(Handle<SharedFunctionInfo> shared,
2510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                          BailoutId node_id) {
2511109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (shared->HasBytecodeArray()) {
2512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    BytecodeArray* bytecodes = shared->bytecode_array();
2513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return bytecodes->SourcePosition(node_id.ToInt());
2514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
2515109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Code* non_optimized_code = shared->code();
2516109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    FixedArray* raw_data = non_optimized_code->deoptimization_data();
2517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
2518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, *shared);
2519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
2520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return non_optimized_code->SourcePosition(pc_offset);
25218389745919cae02139ddc085a63c00d024269cf2Ben Murdoch  }
2522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
25238389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}  // namespace
2525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochDeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state,
2527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                           TranslatedState::iterator frame_it,
2528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                           Isolate* isolate) {
2529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If the previous frame is an adaptor frame, we will take the parameters
2530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // from there.
2531109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedState::iterator parameter_frame = frame_it;
2532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (parameter_frame != state->begin()) {
2533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_frame--;
25348389745919cae02139ddc085a63c00d024269cf2Ben Murdoch  }
2535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count;
2536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (parameter_frame->kind() == TranslatedFrame::kArgumentsAdaptor) {
2537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_count = parameter_frame->height() - 1;  // Ignore the receiver.
2538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
2539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_frame = frame_it;
2540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_count =
2541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        frame_it->shared_info()->internal_formal_parameter_count();
2542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedFrame::iterator parameter_it = parameter_frame->begin();
2544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  parameter_it++;  // Skip the function.
2545109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  parameter_it++;  // Skip the receiver.
25468389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2547109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Figure out whether there is a construct stub frame on top of
2548109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // the parameter frame.
2549109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  has_construct_stub_ =
2550109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      parameter_frame != state->begin() &&
2551109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      (parameter_frame - 1)->kind() == TranslatedFrame::kConstructStub;
25528389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  source_position_ =
2554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      ComputeSourcePosition(frame_it->shared_info(), frame_it->node_id());
2555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2556109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedFrame::iterator value_it = frame_it->begin();
2557109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get the function. Note that this might materialize the function.
2558109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // In case the debugger mutates this value, we should deoptimize
2559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // the function and remember the value in the materialized value store.
2560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  function_ = Handle<JSFunction>::cast(value_it->GetValue());
2561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  parameters_.resize(static_cast<size_t>(parameter_count));
2563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < parameter_count; i++) {
2564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Handle<Object> parameter = GetValueForDebugger(parameter_it, isolate);
2565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    SetParameter(i, parameter);
2566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_it++;
2567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Skip the function, the receiver and the arguments.
2570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int skip_count =
2571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      frame_it->shared_info()->internal_formal_parameter_count() + 2;
2572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedFrame::iterator stack_it = frame_it->begin();
2573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < skip_count; i++) {
2574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    stack_it++;
2575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get the context.
2578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  context_ = GetValueForDebugger(stack_it, isolate);
2579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  stack_it++;
2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get the expression stack.
2582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int stack_height = frame_it->height();
2583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (frame_it->kind() == TranslatedFrame::kFunction ||
2584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
2585109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // For full-code frames, we should not count the context.
2586109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // For interpreter frames, we should not count the accumulator.
2587109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // TODO(jarin): Clean up the indexing in translated frames.
2588109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    stack_height--;
2589109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2590109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  expression_stack_.resize(static_cast<size_t>(stack_height));
2591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < stack_height; i++) {
2592109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Handle<Object> expression = GetValueForDebugger(stack_it, isolate);
2593109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    SetExpression(i, expression);
2594109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    stack_it++;
2595109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2597109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // For interpreter frame, skip the accumulator.
2598109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
2599109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    stack_it++;
2600109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2601109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK(stack_it == frame_it->end());
2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) {
2606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(deopt_reason < kLastDeoptReason);
2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DEOPT_MESSAGES_TEXTS(C, T) T,
2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const char* deopt_messages_[] = {
2609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)};
2610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DEOPT_MESSAGES_TEXTS
2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return deopt_messages_[deopt_reason];
2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDeoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, Address pc) {
2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePosition last_position = SourcePosition::Unknown();
2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Deoptimizer::DeoptReason last_reason = Deoptimizer::kNoReason;
2618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int mask = RelocInfo::ModeMask(RelocInfo::DEOPT_REASON) |
2619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             RelocInfo::ModeMask(RelocInfo::POSITION);
2620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (RelocIterator it(code, mask); !it.done(); it.next()) {
2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RelocInfo* info = it.rinfo();
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (info->pc() >= pc) return DeoptInfo(last_position, NULL, last_reason);
2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (info->rmode() == RelocInfo::POSITION) {
2624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int raw_position = static_cast<int>(info->data());
2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_position = raw_position ? SourcePosition::FromRaw(raw_position)
2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   : SourcePosition::Unknown();
2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (info->rmode() == RelocInfo::DEOPT_REASON) {
2628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_reason = static_cast<Deoptimizer::DeoptReason>(info->data());
2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return DeoptInfo(SourcePosition::Unknown(), NULL, Deoptimizer::kNoReason);
2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container,
2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int length,
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int object_index) {
2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kArgumentsObject);
2640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.materialization_info_ = {object_index, length};
2641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container,
2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   int length,
2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   int object_index) {
2649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kCapturedObject);
2650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.materialization_info_ = {object_index, length};
2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewDuplicateObject(TranslatedState* container,
2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int id) {
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kDuplicatedObject);
2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.materialization_info_ = {id, -1};
2660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewDouble(TranslatedState* container,
2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           double value) {
2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kDouble);
2668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.double_value_ = value;
2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewInt32(TranslatedState* container,
2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          int32_t value) {
2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kInt32);
2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.int32_value_ = value;
2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewUInt32(TranslatedState* container,
2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           uint32_t value) {
2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kUInt32);
2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.uint32_value_ = value;
2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewBool(TranslatedState* container,
2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         uint32_t value) {
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kBoolBit);
2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.uint32_value_ = value;
2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewTagged(TranslatedState* container,
2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           Object* literal) {
2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kTagged);
2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.raw_literal_ = literal;
2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewInvalid(TranslatedState* container) {
2711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedValue(container, kInvalid);
2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochIsolate* TranslatedValue::isolate() const { return container_->isolate(); }
2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* TranslatedValue::raw_literal() const {
2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kTagged, kind());
2720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return raw_literal_;
2721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint32_t TranslatedValue::int32_value() const {
2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kInt32, kind());
2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return int32_value_;
2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochuint32_t TranslatedValue::uint32_value() const {
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind() == kUInt32 || kind() == kBoolBit);
2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return uint32_value_;
2733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble TranslatedValue::double_value() const {
2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kDouble, kind());
2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return double_value_;
2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedValue::object_length() const {
2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind() == kArgumentsObject || kind() == kCapturedObject);
2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return materialization_info_.length_;
2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedValue::object_index() const {
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind() == kArgumentsObject || kind() == kCapturedObject ||
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         kind() == kDuplicatedObject);
2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return materialization_info_.id_;
2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* TranslatedValue::GetRawValue() const {
2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we have a value, return it.
2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> result_handle;
2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value_.ToHandle(&result_handle)) {
2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return *result_handle;
2760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Otherwise, do a best effort to get the value without allocation.
2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kTagged:
2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return raw_literal();
2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInt32: {
2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_smi = Smi::IsValid(int32_value());
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (is_smi) {
2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Smi::FromInt(int32_value());
2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUInt32: {
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_smi = (uint32_value() <= static_cast<uintptr_t>(Smi::kMaxValue));
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (is_smi) {
2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Smi::FromInt(static_cast<int32_t>(uint32_value()));
2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kBoolBit: {
2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (uint32_value() == 0) {
2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate()->heap()->false_value();
2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        CHECK_EQ(1U, uint32_value());
2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate()->heap()->true_value();
2789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we could not get the value without allocation, return the arguments
2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // marker.
2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return isolate()->heap()->arguments_marker();
2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> TranslatedValue::GetValue() {
2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> result;
2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we already have a value, then get it.
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value_.ToHandle(&result)) return result;
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Otherwise we have to materialize.
2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kTagged:
2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInt32:
2811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kUInt32:
2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kBoolBit:
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDouble: {
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MaterializeSimple();
2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return value_.ToHandleChecked();
2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kArgumentsObject:
2819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kCapturedObject:
2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDuplicatedObject:
2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return container_->MaterializeObjectAt(object_index());
2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInvalid:
2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FATAL("unexpected case");
2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Handle<Object>::null();
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FATAL("internal error: value missing");
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<Object>::null();
2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedValue::MaterializeSimple() {
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we already have materialized, return.
2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!value_.is_null()) return;
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* raw_value = GetRawValue();
2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (raw_value != isolate()->heap()->arguments_marker()) {
2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We can get the value without allocation, just return it here.
2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ = Handle<Object>(raw_value, isolate());
2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInt32: {
2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(int32_value()));
2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUInt32:
2851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(uint32_value()));
2852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDouble:
2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(double_value()));
2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCapturedObject:
2859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDuplicatedObject:
2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArgumentsObject:
2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInvalid:
2862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kTagged:
2863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kBoolBit:
2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FATAL("internal error: unexpected materialization.");
2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool TranslatedValue::IsMaterializedObject() const {
2871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCapturedObject:
2873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDuplicatedObject:
2874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArgumentsObject:
2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool TranslatedValue::IsMaterializableByDebugger() const {
2882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // At the moment, we only allow materialization of doubles.
2883109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return (kind() == kDouble);
2884109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedValue::GetChildrenCount() const {
2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kind() == kCapturedObject || kind() == kArgumentsObject) {
2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return object_length();
2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return 0;
2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochuint32_t TranslatedState::GetUInt32Slot(Address fp, int slot_offset) {
2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address address = fp + slot_offset;
2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_BIG_ENDIAN && V8_HOST_ARCH_64_BIT
2898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::uint32_at(address + kIntSize);
2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else
2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::uint32_at(address);
2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedValue::Handlify() {
2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kind() == kTagged) {
2907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ = Handle<Object>(raw_literal(), isolate());
2908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    raw_literal_ = nullptr;
2909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id,
2914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         SharedFunctionInfo* shared_info,
2915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         int height) {
2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info,
2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        height);
2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame.node_id_ = node_id;
2919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return frame;
2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::InterpretedFrame(
2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BailoutId bytecode_offset, SharedFunctionInfo* shared_info, int height) {
2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame frame(kInterpretedFunction, shared_info->GetIsolate(),
2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        shared_info, height);
2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame.node_id_ = bytecode_offset;
2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return frame;
2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::AccessorFrame(
2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Kind kind, SharedFunctionInfo* shared_info) {
2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind == kSetter || kind == kGetter);
2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info);
2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame(
2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SharedFunctionInfo* shared_info, int height) {
2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(),
2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         shared_info, height);
2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::ConstructStubFrame(
2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SharedFunctionInfo* shared_info, int height) {
2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info,
2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         height);
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedFrame::GetValueCount() {
2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFunction: {
2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int parameter_count =
2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          raw_shared_info_->internal_formal_parameter_count() + 1;
2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // + 1 for function.
2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return height_ + parameter_count + 1;
2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInterpretedFunction: {
2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int parameter_count =
2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          raw_shared_info_->internal_formal_parameter_count() + 1;
2965109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // + 2 for function and context.
2966109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return height_ + parameter_count + 2;
2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kGetter:
2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;  // Function and receiver.
2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSetter:
2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 3;  // Function, receiver and the value to set.
2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArgumentsAdaptor:
2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kConstructStub:
2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 1 + height_;
2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCompiledStub:
2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return height_;
2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInvalid:
2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedFrame::Handlify() {
2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (raw_shared_info_ != nullptr) {
2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    shared_info_ = Handle<SharedFunctionInfo>(raw_shared_info_);
2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    raw_shared_info_ = nullptr;
2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& value : values_) {
2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value.Handlify();
2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedState::CreateNextTranslatedFrame(
3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslationIterator* iterator, FixedArray* literal_array, Address fp,
3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FILE* trace_file) {
3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode opcode =
3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (opcode) {
3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::JS_FRAME: {
3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BailoutId node_id = BailoutId(iterator->Next());
3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading input frame %s", name.get());
3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int arg_count = shared_info->internal_formal_parameter_count() + 1;
3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n",
3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               node_id.ToInt(), arg_count, height);
3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::JSFrame(node_id, shared_info, height);
3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INTERPRETED_FRAME: {
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BailoutId bytecode_offset = BailoutId(iterator->Next());
3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading input frame %s", name.get());
3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int arg_count = shared_info->internal_formal_parameter_count() + 1;
3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file,
3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               " => bytecode_offset=%d, args=%d, height=%d; inputs:\n",
3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               bytecode_offset.ToInt(), arg_count, height);
3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::InterpretedFrame(bytecode_offset, shared_info,
3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               height);
3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::ARGUMENTS_ADAPTOR_FRAME: {
3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading arguments adaptor frame %s", name.get());
3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, " => height=%d; inputs:\n", height);
3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height);
3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::CONSTRUCT_STUB_FRAME: {
3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading construct stub frame %s", name.get());
3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, " => height=%d; inputs:\n", height);
3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::ConstructStubFrame(shared_info, height);
3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::GETTER_STUB_FRAME: {
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading getter frame %s; inputs:\n", name.get());
3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter,
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            shared_info);
3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::SETTER_STUB_FRAME: {
3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        base::SmartArrayPointer<char> name =
3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            shared_info->DebugName()->ToCString();
3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading setter frame %s; inputs:\n", name.get());
3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::AccessorFrame(TranslatedFrame::kSetter,
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            shared_info);
3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::COMPILED_STUB_FRAME: {
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file,
3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               "  reading compiler stub frame => height=%d; inputs:\n", height);
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::CompiledStubFrame(height,
3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                literal_array->GetIsolate());
3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BEGIN:
3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DUPLICATED_OBJECT:
3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::ARGUMENTS_OBJECT:
3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::CAPTURED_OBJECT:
3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::REGISTER:
3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INT32_REGISTER:
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::UINT32_REGISTER:
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_REGISTER:
3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DOUBLE_REGISTER:
3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::STACK_SLOT:
3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INT32_STACK_SLOT:
3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::UINT32_STACK_SLOT:
3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_STACK_SLOT:
3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DOUBLE_STACK_SLOT:
3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::LITERAL:
3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FATAL("We should never get here - unexpected deopt info.");
3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame::InvalidFrame();
3121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
3122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedFrame::AdvanceIterator(
3126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    std::deque<TranslatedValue>::iterator* iter) {
3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int values_to_skip = 1;
3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (values_to_skip > 0) {
3129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Consume the current element.
3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values_to_skip--;
3131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Add all the children.
3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values_to_skip += (*iter)->GetChildrenCount();
3133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    (*iter)++;
3135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
3137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
31398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// We can't intermix stack decoding and allocations because
31408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// deoptimization infrastracture is not GC safe.
31418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Thus we build a temporary structure in malloced space.
3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedState::CreateNextTranslatedValue(
3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int frame_index, int value_index, TranslationIterator* iterator,
3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedArray* literal_array, Address fp, RegisterValues* registers,
3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FILE* trace_file) {
3146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  disasm::NameConverter converter;
3147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode opcode =
3149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
31508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  switch (opcode) {
31518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::BEGIN:
31523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case Translation::JS_FRAME:
3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INTERPRETED_FRAME:
31543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case Translation::ARGUMENTS_ADAPTOR_FRAME:
31553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case Translation::CONSTRUCT_STUB_FRAME:
3156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::GETTER_STUB_FRAME:
3157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::SETTER_STUB_FRAME:
3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::COMPILED_STUB_FRAME:
31598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      // Peeled off before getting here.
31608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      break;
31618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::DUPLICATED_OBJECT: {
3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_id = iterator->Next();
3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "duplicated object #%d", object_id);
3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_positions_.push_back(object_positions_[object_id]);
3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDuplicateObject(this, object_id);
3169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::ARGUMENTS_OBJECT: {
3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int arg_count = iterator->Next();
3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_index = static_cast<int>(object_positions_.size());
3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "argumets object #%d (length = %d)", object_index,
3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               arg_count);
3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_positions_.push_back({frame_index, value_index});
3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewArgumentsObject(this, arg_count, object_index);
3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::CAPTURED_OBJECT: {
3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int field_count = iterator->Next();
3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_index = static_cast<int>(object_positions_.size());
3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "captured object #%d (length = %d)", object_index,
3187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               field_count);
3188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_positions_.push_back({frame_index, value_index});
3190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDeferredObject(this, field_count,
3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                object_index);
3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
31938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::REGISTER: {
3195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; %s ", value,
3200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INT32_REGISTER: {
3207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%" V8PRIdPTR " ; %s ", value,
3212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewInt32(this, static_cast<int32_t>(value));
3215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::UINT32_REGISTER: {
3218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%" V8PRIuPTR " ; %s (uint)", value,
3223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value));
3227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_REGISTER: {
3230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%" V8PRIdPTR " ; %s (bool)", value,
3235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewBool(this, static_cast<uint32_t>(value));
3238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DOUBLE_REGISTER: {
3241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      double value = registers->GetDoubleRegister(input_reg);
3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%e ; %s (bool)", value,
3246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               DoubleRegister::from_code(input_reg).ToString());
3247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDouble(this, value);
3249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
32508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
32518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::STACK_SLOT: {
3252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset));
3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; [fp %c %d] ", value,
3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
32618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
32628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
32638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::INT32_STACK_SLOT: {
3264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t value = GetUInt32Slot(fp, slot_offset);
3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%d ; (int) [fp %c %d] ",
3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               static_cast<int32_t>(value), slot_offset < 0 ? '-' : '+',
3270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               std::abs(slot_offset));
3271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewInt32(this, value);
32738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
32748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::UINT32_STACK_SLOT: {
3276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t value = GetUInt32Slot(fp, slot_offset);
3279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value,
3281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewUInt32(this, value);
3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_STACK_SLOT: {
3287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t value = GetUInt32Slot(fp, slot_offset);
3290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value,
3292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewBool(this, value);
3295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
32978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::DOUBLE_STACK_SLOT: {
3298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      double value = ReadDoubleValue(fp + slot_offset);
3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%e ; (double) [fp %c %d] ", value,
3303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDouble(this, value);
33068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
33078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
33088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::LITERAL: {
33098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      int literal_index = iterator->Next();
3310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Object* value = literal_array->get(literal_index);
3311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ",
3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               reinterpret_cast<intptr_t>(value), literal_index);
3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewTagged(this, value);
33188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
33198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
33208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("We should never get here - unexpected deopt info.");
3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedValue(nullptr, TranslatedValue::kInvalid);
33238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
33248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
33258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedState::TranslatedState(JavaScriptFrame* frame)
3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : isolate_(nullptr),
3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      stack_frame_pointer_(nullptr),
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_adapted_arguments_(false) {
3330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int deopt_index = Safepoint::kNoDeoptimizationIndex;
33318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  DeoptimizationInputData* data =
33328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
33338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  TranslationIterator it(data->TranslationByteArray(),
33348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                         data->TranslationIndex(deopt_index)->value());
3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Init(frame->fp(), &it, data->LiteralArray(), nullptr /* registers */,
3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       nullptr /* trace file */);
3337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedState::TranslatedState()
3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : isolate_(nullptr),
3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      stack_frame_pointer_(nullptr),
3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_adapted_arguments_(false) {}
3344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::Init(Address input_frame_pointer,
3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           TranslationIterator* iterator,
3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           FixedArray* literal_array, RegisterValues* registers,
3349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           FILE* trace_file) {
3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(frames_.empty());
3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate_ = literal_array->GetIsolate();
3353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read out the 'header' translation.
3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode opcode =
3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(opcode == Translation::BEGIN);
3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int count = iterator->Next();
3359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  iterator->Next();  // Drop JS frames count.
3360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frames_.reserve(count);
3362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::stack<int> nested_counts;
3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read the frames
3366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < count; i++) {
3367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Read the frame descriptor.
3368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frames_.push_back(CreateNextTranslatedFrame(
3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        iterator, literal_array, input_frame_pointer, trace_file));
3370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame& frame = frames_.back();
3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Read the values.
3373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int values_to_process = frame.GetValueCount();
3374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (values_to_process > 0 || !nested_counts.empty()) {
3375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (nested_counts.empty()) {
3377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // For top level values, print the value number.
3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintF(trace_file, "    %3i: ",
3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 frame.GetValueCount() - values_to_process);
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // Take care of indenting for nested values.
3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintF(trace_file, "         ");
3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          for (size_t j = 0; j < nested_counts.size(); j++) {
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintF(trace_file, "  ");
3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedValue value = CreateNextTranslatedValue(
3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          i, static_cast<int>(frame.values_.size()), iterator, literal_array,
3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          input_frame_pointer, registers, trace_file);
3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame.Add(value);
3393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "\n");
3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
33973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Update the value count and resolve the nesting.
3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      values_to_process--;
3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int children_count = value.GetChildrenCount();
3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (children_count > 0) {
3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        nested_counts.push(values_to_process);
3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        values_to_process = children_count;
3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        while (values_to_process == 0 && !nested_counts.empty()) {
3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          values_to_process = nested_counts.top();
3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          nested_counts.pop();
3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
34118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(!iterator->HasNext() ||
3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        static_cast<Translation::Opcode>(iterator->Next()) ==
3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Translation::BEGIN);
3416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
34178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::Prepare(bool has_adapted_arguments,
3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              Address stack_frame_pointer) {
3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& frame : frames_) frame.Handlify();
3422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  stack_frame_pointer_ = stack_frame_pointer;
3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  has_adapted_arguments_ = has_adapted_arguments;
3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UpdateFromPreviouslyMaterializedObjects();
3427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> TranslatedState::MaterializeAt(int frame_index,
3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              int* value_index) {
3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* frame = &(frames_[frame_index]);
3433109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK(static_cast<size_t>(*value_index) < frame->values_.size());
3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue* slot = &(frame->values_[*value_index]);
3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (*value_index)++;
3437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (slot->kind()) {
3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kTagged:
3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInt32:
3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kUInt32:
3442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kBoolBit:
3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDouble: {
3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot->MaterializeSimple();
3445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> value = slot->GetValue();
3446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (value->IsMutableHeapNumber()) {
3447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        HeapNumber::cast(*value)->set_map(isolate()->heap()->heap_number_map());
3448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return value;
3450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kArgumentsObject: {
3453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int length = slot->GetChildrenCount();
3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<JSObject> arguments;
3455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (GetAdaptedArguments(&arguments, frame_index)) {
3456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Store the materialized object and consume the nested values.
3457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (int i = 0; i < length; ++i) {
3458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          MaterializeAt(frame_index, value_index);
3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSFunction> function =
3462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<JSFunction>::cast(frame->front().GetValue());
3463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        arguments = isolate_->factory()->NewArgumentsObject(function, length);
3464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
3465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_EQ(array->length(), length);
3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        arguments->set_elements(*array);
3467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (int i = 0; i < length; ++i) {
3468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> value = MaterializeAt(frame_index, value_index);
3469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          array->set(i, *value);
3470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot->value_ = arguments;
3473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return arguments;
3474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kCapturedObject: {
3476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int length = slot->GetChildrenCount();
3477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The map must be a tagged object.
3479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK(frame->values_[*value_index].kind() == TranslatedValue::kTagged);
3480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> result;
3482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (slot->value_.ToHandle(&result)) {
3483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // This has been previously materialized, return the previous value.
3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // We still need to skip all the nested objects.
3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (int i = 0; i < length; i++) {
3486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          MaterializeAt(frame_index, value_index);
3487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return result;
3490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> map_object = MaterializeAt(frame_index, value_index);
3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Map> map =
3494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Map::GeneralizeAllFieldRepresentations(Handle<Map>::cast(map_object));
3495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      switch (map->instance_type()) {
3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case MUTABLE_HEAP_NUMBER_TYPE:
3497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case HEAP_NUMBER_TYPE: {
3498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Reuse the HeapNumber value directly as it is already properly
3499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // tagged and skip materializing the HeapNumber explicitly.
3500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> object = MaterializeAt(frame_index, value_index);
3501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // On 32-bit architectures, there is an extra slot there because
3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // the escape analysis calculates the number of slots as
3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // object-size/pointer-size. To account for this, we read out
3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // any extra slots.
3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          for (int i = 0; i < length - 2; i++) {
3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            MaterializeAt(frame_index, value_index);
3508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
3509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return object;
3510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case JS_OBJECT_TYPE: {
3512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Handle<JSObject> object =
3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED);
3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> properties = MaterializeAt(frame_index, value_index);
3516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> elements = MaterializeAt(frame_index, value_index);
3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_properties(FixedArray::cast(*properties));
3518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_elements(FixedArrayBase::cast(*elements));
3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          for (int i = 0; i < length - 3; ++i) {
3520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<Object> value = MaterializeAt(frame_index, value_index);
3521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i);
3522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            object->FastPropertyAtPut(index, *value);
3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return object;
3525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case JS_ARRAY_TYPE: {
3527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Handle<JSArray> object =
3528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewJSArray(0, map->elements_kind());
3529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> properties = MaterializeAt(frame_index, value_index);
3531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> elements = MaterializeAt(frame_index, value_index);
3532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> length = MaterializeAt(frame_index, value_index);
3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_properties(FixedArray::cast(*properties));
3534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_elements(FixedArrayBase::cast(*elements));
3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_length(*length);
3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return object;
3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case FIXED_ARRAY_TYPE: {
3539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> lengthObject = MaterializeAt(frame_index, value_index);
3540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int32_t length = 0;
3541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CHECK(lengthObject->ToInt32(&length));
3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<FixedArray> object =
3543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewFixedArray(length);
3544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // We need to set the map, because the fixed array we are
3545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // materializing could be a context or an arguments object,
3546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // in which case we must retain that information.
3547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          object->set_map(*map);
3548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          for (int i = 0; i < length; ++i) {
3550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<Object> value = MaterializeAt(frame_index, value_index);
3551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            object->set(i, *value);
3552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return object;
3554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case FIXED_DOUBLE_ARRAY_TYPE: {
3556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map());
3557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> lengthObject = MaterializeAt(frame_index, value_index);
3558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int32_t length = 0;
3559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CHECK(lengthObject->ToInt32(&length));
3560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<FixedArrayBase> object =
3561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewFixedDoubleArray(length);
3562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (length > 0) {
3564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<FixedDoubleArray> double_array =
3565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                Handle<FixedDoubleArray>::cast(object);
3566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            for (int i = 0; i < length; ++i) {
3567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              Handle<Object> value = MaterializeAt(frame_index, value_index);
3568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              CHECK(value->IsNumber());
3569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              double_array->set(i, value->Number());
3570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
3571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return object;
3573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        default:
3575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintF(stderr, "[couldn't handle instance type %d]\n",
3576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 map->instance_type());
3577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          FATAL("unreachable");
3578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return Handle<Object>::null();
3579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
3582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDuplicatedObject: {
3585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_index = slot->object_index();
3586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedState::ObjectPosition pos = object_positions_[object_index];
3587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Make sure the duplicate is refering to a previous object.
3589109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      CHECK(pos.frame_index_ < frame_index ||
3590109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            (pos.frame_index_ == frame_index &&
3591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch             pos.value_index_ < *value_index - 1));
3592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> object =
3594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          frames_[pos.frame_index_].values_[pos.value_index_].GetValue();
3595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The object should have a (non-sentinel) value.
3597109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      CHECK(!object.is_null() &&
3598109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            !object.is_identical_to(isolate_->factory()->arguments_marker()));
3599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot->value_ = object;
3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return object;
3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInvalid:
3605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
3607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("We should never get here - unexpected deopt slot kind.");
3610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Object>::null();
3611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> TranslatedState::MaterializeObjectAt(int object_index) {
3615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedState::ObjectPosition pos = object_positions_[object_index];
3616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return MaterializeAt(pos.frame_index_, &(pos.value_index_));
3617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result,
3621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          int frame_index) {
3622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (frame_index == 0) {
3623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Top level frame -> we need to go to the parent frame on the stack.
3624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!has_adapted_arguments_) return false;
3625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This is top level frame, so we need to go to the stack to get
3627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // this function's argument. (Note that this relies on not inlining
3628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // recursive functions!)
3629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSFunction> function =
3630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSFunction>::cast(frames_[frame_index].front().GetValue());
3631109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    *result = Accessors::FunctionGetArguments(function);
3632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame* previous_frame = &(frames_[frame_index]);
3635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (previous_frame->kind() != TranslatedFrame::kArgumentsAdaptor) {
3636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
3637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We get the adapted arguments from the parent translation.
3639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int length = previous_frame->height();
3640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSFunction> function =
3641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSFunction>::cast(previous_frame->front().GetValue());
3642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSObject> arguments =
3643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_->factory()->NewArgumentsObject(function, length);
3644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
3645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    arguments->set_elements(*array);
3646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame::iterator arg_iterator = previous_frame->begin();
3647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    arg_iterator++;  // Skip function.
3648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < length; ++i) {
3649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> value = arg_iterator->GetValue();
3650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array->set(i, *value);
3651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arg_iterator++;
3652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(arg_iterator == previous_frame->end());
3654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *result = arguments;
3655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex(
3661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int jsframe_index, int* args_count) {
3662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < frames_.size(); i++) {
3663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (frames_[i].kind() == TranslatedFrame::kFunction ||
3664109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        frames_[i].kind() == TranslatedFrame::kInterpretedFunction) {
3665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (jsframe_index > 0) {
3666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        jsframe_index--;
3667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // We have the JS function frame, now check if it has arguments adaptor.
3669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (i > 0 &&
3670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            frames_[i - 1].kind() == TranslatedFrame::kArgumentsAdaptor) {
3671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          *args_count = frames_[i - 1].height();
3672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return &(frames_[i - 1]);
3673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        *args_count =
3675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            frames_[i].shared_info()->internal_formal_parameter_count() + 1;
3676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return &(frames_[i]);
3677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
3681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::StoreMaterializedValuesAndDeopt() {
3685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaterializedObjectStore* materialized_store =
3686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_->materialized_object_store();
3687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> previously_materialized_objects =
3688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      materialized_store->Get(stack_frame_pointer_);
3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> marker = isolate_->factory()->arguments_marker();
3691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length = static_cast<int>(object_positions_.size());
3693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool new_store = false;
3694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (previously_materialized_objects.is_null()) {
3695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    previously_materialized_objects =
3696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_->factory()->NewFixedArray(length);
3697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < length; i++) {
3698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      previously_materialized_objects->set(i, *marker);
3699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_store = true;
3701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3703109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK_EQ(length, previously_materialized_objects->length());
3704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool value_changed = false;
3706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < length; i++) {
3707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedState::ObjectPosition pos = object_positions_[i];
3708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedValue* value_info =
3709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &(frames_[pos.frame_index_].values_[pos.value_index_]);
3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK(value_info->IsMaterializedObject());
3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> value(value_info->GetRawValue(), isolate_);
3714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!value.is_identical_to(marker)) {
3716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (previously_materialized_objects->get(i) == *marker) {
3717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        previously_materialized_objects->set(i, *value);
3718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value_changed = true;
3719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3720109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CHECK(previously_materialized_objects->get(i) == *value);
3721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_store && value_changed) {
3725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    materialized_store->Set(stack_frame_pointer_,
3726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            previously_materialized_objects);
3727109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK(frames_[0].kind() == TranslatedFrame::kFunction ||
3728109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          frames_[0].kind() == TranslatedFrame::kInterpretedFunction);
3729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object* const function = frames_[0].front().GetRawValue();
3730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Deoptimizer::DeoptimizeFunction(JSFunction::cast(function));
3731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
37328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
37338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
37348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::UpdateFromPreviouslyMaterializedObjects() {
3736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaterializedObjectStore* materialized_store =
3737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_->materialized_object_store();
3738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> previously_materialized_objects =
3739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      materialized_store->Get(stack_frame_pointer_);
37403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we have no previously materialized objects, there is nothing to do.
3742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (previously_materialized_objects.is_null()) return;
37433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> marker = isolate_->factory()->arguments_marker();
37453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length = static_cast<int>(object_positions_.size());
3747109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK_EQ(length, previously_materialized_objects->length());
37483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < length; i++) {
3750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // For a previously materialized objects, inject their value into the
3751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // translated values.
3752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (previously_materialized_objects->get(i) != *marker) {
3753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedState::ObjectPosition pos = object_positions_[i];
3754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedValue* value_info =
3755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          &(frames_[pos.frame_index_].values_[pos.value_index_]);
3756109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      CHECK(value_info->IsMaterializedObject());
37573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_info->value_ =
3759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object>(previously_materialized_objects->get(i), isolate_);
3760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
37623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
37633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
3765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
3766