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
7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <memory>
8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/accessors.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/prettyprinter.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/disasm.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames-inl.h"
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/full-codegen/full-codegen.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h"
16109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interpreter/interpreter.h"
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h"
18109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/tracing/trace-event.h"
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/v8.h"
20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 {
23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal {
24b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic MemoryChunk* AllocateCodeChunk(MemoryAllocator* allocator) {
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return allocator->AllocateChunk(Deoptimizer::GetMaxDeoptTableSize(),
27c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  MemoryAllocator::GetCommitPageSize(),
28c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  EXECUTABLE, NULL);
2944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDeoptimizerData::DeoptimizerData(MemoryAllocator* allocator)
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : allocator_(allocator),
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      current_(NULL) {
353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (int i = 0; i <= Deoptimizer::kLastBailoutType; ++i) {
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt_entry_code_entries_[i] = -1;
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt_entry_code_[i] = AllocateCodeChunk(allocator);
3844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDeoptimizerData::~DeoptimizerData() {
433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (int i = 0; i <= Deoptimizer::kLastBailoutType; ++i) {
44bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    allocator_->Free<MemoryAllocator::kFull>(deopt_entry_code_[i]);
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt_entry_code_[i] = NULL;
4644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
4844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* Deoptimizer::FindDeoptimizingCode(Address addr) {
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (function_->IsHeapObject()) {
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Search all deoptimizing code in the native context of the function.
5313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Isolate* isolate = function_->GetIsolate();
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = function_->context()->native_context();
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* element = native_context->DeoptimizedCodeListHead();
5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    while (!element->IsUndefined(isolate)) {
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = Code::cast(element);
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (code->contains(addr)) return code;
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      element = code->next_code_link();
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// We rely on this function not causing a GC.  It is called from generated code
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// without having a real stack frame in place.
69b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer* Deoptimizer::New(JSFunction* function,
70b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              BailoutType type,
71b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              unsigned bailout_id,
72b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              Address from,
7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                              int fp_to_sp_delta,
7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                              Isolate* isolate) {
75f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Deoptimizer* deoptimizer = new Deoptimizer(isolate, function, type,
76f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                             bailout_id, from, fp_to_sp_delta);
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(isolate->deoptimizer_data()->current_ == NULL);
7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->deoptimizer_data()->current_ = deoptimizer;
79b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return deoptimizer;
80b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
81b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// No larger than 2K on all platforms
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kDeoptTableMaxEpilogueCodeSize = 2 * KB;
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t Deoptimizer::GetMaxDeoptTableSize() {
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int entries_size =
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_;
90c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int commit_page_size = static_cast<int>(MemoryAllocator::GetCommitPageSize());
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) /
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    commit_page_size) + 1;
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<size_t>(commit_page_size * page_count);
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDeoptimizer* Deoptimizer::Grab(Isolate* isolate) {
9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Deoptimizer* result = isolate->deoptimizer_data()->current_;
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NOT_NULL(result);
100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  result->DeleteFrameDescriptions();
10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->deoptimizer_data()->current_ = NULL;
102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1053fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochDeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    JavaScriptFrame* frame,
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int jsframe_index,
1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    Isolate* isolate) {
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame->is_optimized());
110f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
111109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedState translated_values(frame);
112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  translated_values.Prepare(false, frame->fp());
113109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
114109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedState::iterator frame_it = translated_values.end();
115109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int counter = jsframe_index;
116109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (auto it = translated_values.begin(); it != translated_values.end();
117109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch       it++) {
118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (it->kind() == TranslatedFrame::kFunction ||
119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        it->kind() == TranslatedFrame::kInterpretedFunction) {
120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (counter == 0) {
121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        frame_it = it;
122109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        break;
123109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      counter--;
125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
126109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK(frame_it != translated_values.end());
128f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DeoptimizedFrameInfo* info =
130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new DeoptimizedFrameInfo(&translated_values, frame_it, isolate);
1313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return info;
1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                int count,
137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                BailoutType type) {
138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TableEntryGenerator generator(masm, type, count);
139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  generator.Generate();
140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::VisitAllOptimizedFunctionsForContext(
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* context, OptimizedFunctionVisitor* visitor) {
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(context->IsNativeContext());
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  visitor->EnterContext(context);
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit the list of optimized functions, removing elements that
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // no longer refer to optimized code.
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSFunction* prev = NULL;
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* element = context->OptimizedFunctionsListHead();
15413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Isolate* isolate = context->GetIsolate();
15513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (!element->IsUndefined(isolate)) {
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    JSFunction* function = JSFunction::cast(element);
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* next = function->next_function_link();
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (function->code()->kind() != Code::OPTIMIZED_FUNCTION ||
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (visitor->VisitFunction(function),
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         function->code()->kind() != Code::OPTIMIZED_FUNCTION)) {
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The function no longer refers to optimized code, or the visitor
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // changed the code to which it refers to no longer be optimized code.
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Remove the function from this list.
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (prev != NULL) {
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        prev->set_next_function_link(next, UPDATE_WEAK_WRITE_BARRIER);
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        context->SetOptimizedFunctionsListHead(next);
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The visitor should not alter the link directly.
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK_EQ(function->next_function_link(), next);
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Set the next function link to undefined to indicate it is no longer
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // in the optimized functions list.
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      function->set_next_function_link(context->GetHeap()->undefined_value(),
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       SKIP_WRITE_BARRIER);
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The visitor should not alter the link directly.
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK_EQ(function->next_function_link(), next);
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // preserve this element.
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      prev = function;
180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element = next;
182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  visitor->LeaveContext(context);
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::VisitAllOptimizedFunctions(
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    OptimizedFunctionVisitor* visitor) {
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Run through the list of all native contexts.
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
19513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (!context->IsUndefined(isolate)) {
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor);
197bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    context = Context::cast(context)->next_context_link();
198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Unlink functions referring to code marked for deoptimization, then move
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// marked code from the optimized code list to the deoptimized code list,
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and patch code for lazy deopt.
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) {
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A "closure" that unlinks optimized code that is going to be
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deoptimized from the functions that refer to it.
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class SelectedCodeUnlinker: public OptimizedFunctionVisitor {
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void EnterContext(Context* context) { }  // Don't care.
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void LeaveContext(Context* context)  { }  // Don't care.
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void VisitFunction(JSFunction* function) {
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = function->code();
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!code->marked_for_deoptimization()) return;
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Unlink this function and evict from optimized code map.
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SharedFunctionInfo* shared = function->shared();
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function->set_code(shared->code());
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_trace_deopt) {
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(), "[deoptimizer unlinked: ");
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        function->PrintName(scope.file());
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(),
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Unlink all functions that refer to marked code.
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SelectedCodeUnlinker unlinker;
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitAllOptimizedFunctionsForContext(context, &unlinker);
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate = context->GetHeap()->isolate();
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* topmost_optimized_code = NULL;
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool safe_to_deopt_topmost_optimized_code = false;
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Make sure all activations of optimized code can deopt at their current PC.
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The topmost optimized code has special handling because it cannot be
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deoptimized due to weak object dependency.
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (StackFrameIterator it(isolate, isolate->thread_local_top());
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       !it.done(); it.Advance()) {
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StackFrame::Type type = it.frame()->type();
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (type == StackFrame::OPTIMIZED) {
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = it.frame()->LookupCode();
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      JSFunction* function =
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<OptimizedFrame*>(it.frame())->function();
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_trace_deopt) {
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CodeTracer::Scope scope(isolate->GetCodeTracer());
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(), "[deoptimizer found activation of function: ");
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        function->PrintName(scope.file());
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(scope.file(),
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SafepointEntry safepoint = code->GetSafepointEntry(it.frame()->pc());
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int deopt_index = safepoint.deoptimization_index();
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Turbofan deopt is checked when we are patching addresses on stack.
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool turbofanned = code->is_turbofanned() &&
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         function->shared()->asm_function() &&
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         !FLAG_turbo_asm_deoptimization;
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool safe_to_deopt =
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          deopt_index != Safepoint::kNoDeoptimizationIndex || turbofanned;
265bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      bool builtin = code->kind() == Code::BUILTIN;
266bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CHECK(topmost_optimized_code == NULL || safe_to_deopt || turbofanned ||
267bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            builtin);
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (topmost_optimized_code == NULL) {
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        topmost_optimized_code = code;
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        safe_to_deopt_topmost_optimized_code = safe_to_deopt;
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Move marked code from the optimized code list to the deoptimized
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code list, collecting them into a ZoneList.
278c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Zone zone(isolate->allocator(), ZONE_NAME);
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Code*> codes(10, &zone);
280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Walk over all optimized code objects in this native context.
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* prev = NULL;
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* element = context->OptimizedCodeListHead();
28413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (!element->IsUndefined(isolate)) {
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* code = Code::cast(element);
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* next = code->next_code_link();
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (code->marked_for_deoptimization()) {
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Put the code into the list for later patching.
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      codes.Add(code, &zone);
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (prev != NULL) {
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Skip this code in the optimized code list.
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        prev->set_next_code_link(next);
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // There was no previous node, the next node is the new head.
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        context->SetOptimizedCodeListHead(next);
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Move the code to the _deoptimized_ code list.
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code->set_next_code_link(context->DeoptimizedCodeListHead());
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      context->SetDeoptimizedCodeListHead(code);
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Not marked; preserve this element.
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      prev = code;
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element = next;
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
311109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // We need a handle scope only because of the macro assembler,
312109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // which is used in code patching in EnsureCodeForDeoptimizationEntry.
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate);
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Now patch all the codes for deoptimization.
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < codes.length(); i++) {
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (codes[i] == topmost_optimized_code) {
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(safe_to_deopt_topmost_optimized_code);
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // It is finally time to die, code object.
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Remove the code from optimized code map.
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizationInputData* deopt_data =
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DeoptimizationInputData::cast(codes[i]->deoptimization_data());
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SharedFunctionInfo* shared =
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo());
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    shared->EvictFromOptimizedCodeMap(codes[i], "deoptimized code");
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Do platform-specific patching to force any activations to lazy deopt.
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PatchCodeForDeoptimization(isolate, codes[i]);
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We might be in the middle of incremental marking with compaction.
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Tell collector to treat this code object in a special way and
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // ignore all slots that might have been recorded on it.
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]);
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeAll(Isolate* isolate) {
343bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RuntimeCallTimerScope runtimeTimer(isolate,
344bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     &RuntimeCallStats::DeoptimizeCode);
345109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  TRACE_EVENT0("v8", "V8.DeoptimizeCode");
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trace_deopt) {
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CodeTracer::Scope scope(isolate->GetCodeTracer());
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(scope.file(), "[deoptimize all code in all contexts]\n");
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For all contexts, mark all code, then deoptimize.
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
35413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (!context->IsUndefined(isolate)) {
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = Context::cast(context);
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkAllCodeForContext(native_context);
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizeMarkedCodeForContext(native_context);
358bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    context = native_context->next_context_link();
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) {
364bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RuntimeCallTimerScope runtimeTimer(isolate,
365bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     &RuntimeCallStats::DeoptimizeCode);
366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
367f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  TRACE_EVENT0("v8", "V8.DeoptimizeCode");
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trace_deopt) {
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CodeTracer::Scope scope(isolate->GetCodeTracer());
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(scope.file(), "[deoptimize marked code in all contexts]\n");
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For all contexts, deoptimize code already marked.
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
37513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (!context->IsUndefined(isolate)) {
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = Context::cast(context);
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizeMarkedCodeForContext(native_context);
378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    context = native_context->next_context_link();
379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::MarkAllCodeForContext(Context* context) {
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* element = context->OptimizedCodeListHead();
38513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Isolate* isolate = context->GetIsolate();
38613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (!element->IsUndefined(isolate)) {
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* code = Code::cast(element);
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code->set_marked_for_deoptimization(true);
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element = code->next_code_link();
391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::DeoptimizeFunction(JSFunction* function) {
396bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Isolate* isolate = function->GetIsolate();
397bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RuntimeCallTimerScope runtimeTimer(isolate,
398bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     &RuntimeCallStats::DeoptimizeCode);
399bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
400f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  TRACE_EVENT0("v8", "V8.DeoptimizeCode");
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* code = function->code();
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (code->kind() == Code::OPTIMIZED_FUNCTION) {
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Mark the code for deoptimization and unlink any functions that also
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // refer to that code. The code cannot be shared across native contexts,
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // so we only need to search one.
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code->set_marked_for_deoptimization(true);
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizeMarkedCodeForContext(function->context()->native_context());
408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  deoptimizer->DoComputeOutputFrames();
414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool Deoptimizer::TraceEnabledFor(StackFrame::Type frame_type) {
417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return (frame_type == StackFrame::STUB) ? FLAG_trace_stub_failures
418f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          : FLAG_trace_deopt;
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* Deoptimizer::MessageFor(BailoutType type) {
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (type) {
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EAGER: return "eager";
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SOFT: return "soft";
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LAZY: return "lazy";
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("Unsupported deopt type");
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDeoptimizer::Deoptimizer(Isolate* isolate, JSFunction* function,
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         BailoutType type, unsigned bailout_id, Address from,
434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         int fp_to_sp_delta)
43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : isolate_(isolate),
43644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      function_(function),
437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bailout_id_(bailout_id),
438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bailout_type_(type),
439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      from_(from),
440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      fp_to_sp_delta_(fp_to_sp_delta),
441109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      deoptimizing_throw_(false),
442109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      catch_handler_data_(-1),
443109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      catch_handler_pc_offset_(-1),
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      input_(nullptr),
445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_count_(0),
4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      jsframe_count_(0),
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_(nullptr),
4483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      caller_frame_top_(0),
4493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      caller_fp_(0),
4503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      caller_pc_(0),
4513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      caller_constant_pool_(0),
4523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      input_frame_context_(0),
4533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      stack_fp_(0),
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      trace_scope_(nullptr) {
455109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (isolate->deoptimizer_lazy_throw()) {
456109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    isolate->set_deoptimizer_lazy_throw(false);
457109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    deoptimizing_throw_ = true;
458109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
459109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For COMPILED_STUBs called from builtins, the function pointer is a SMI
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // indicating an internal frame.
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (function->IsSmi()) {
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    function = nullptr;
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(from != nullptr);
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (function != nullptr && function->IsOptimized()) {
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    function->shared()->increment_deopt_count();
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (bailout_type_ == Deoptimizer::SOFT) {
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->counters()->soft_deopts_executed()->Increment();
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Soft deopts shouldn't count against the overall re-optimization count
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // that can eventually lead to disabling optimization for a function.
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int opt_count = function->shared()->opt_count();
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (opt_count > 0) opt_count--;
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function->shared()->set_opt_count(opt_count);
4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
477f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  compiled_code_ = FindOptimizedCode(function);
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if DEBUG
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(compiled_code_ != NULL);
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == EAGER || type == SOFT || type == LAZY) {
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(compiled_code_->kind() != Code::FUNCTION);
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackFrame::Type frame_type = function == NULL
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? StackFrame::STUB
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : StackFrame::JAVA_SCRIPT;
488f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  trace_scope_ = TraceEnabledFor(frame_type)
489f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                     ? new CodeTracer::Scope(isolate->GetCodeTracer())
490f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                     : NULL;
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(AllowHeapAllocation::IsAllowed());
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  disallow_heap_allocation_ = new DisallowHeapAllocation();
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PROFILE(isolate_, CodeDeoptEvent(compiled_code_, from_, fp_to_sp_delta_));
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned size = ComputeInputFrameSize();
499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count =
500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      function == nullptr
501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          ? 0
502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          : (function->shared()->internal_formal_parameter_count() + 1);
503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  input_ = new (size) FrameDescription(size, parameter_count);
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  input_->SetFrameType(frame_type);
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
507f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochCode* Deoptimizer::FindOptimizedCode(JSFunction* function) {
508f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Code* compiled_code = FindDeoptimizingCode(from_);
509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return (compiled_code == NULL)
510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             ? static_cast<Code*>(isolate_->FindCodeObject(from_))
511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             : compiled_code;
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::PrintFunctionName() {
51613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (function_ != nullptr && function_->IsJSFunction()) {
517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    function_->ShortPrint(trace_scope_->file());
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "%s", Code::Kind2String(compiled_code_->kind()));
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer::~Deoptimizer() {
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(input_ == NULL && output_ == NULL);
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(disallow_heap_allocation_ == NULL);
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete trace_scope_;
529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DeleteFrameDescriptions() {
533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete input_;
534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < output_count_; ++i) {
535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (output_[i] != input_) delete output_[i];
536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete[] output_;
538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  input_ = NULL;
539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  output_ = NULL;
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(!AllowHeapAllocation::IsAllowed());
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(disallow_heap_allocation_ != NULL);
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete disallow_heap_allocation_;
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  disallow_heap_allocation_ = NULL;
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            int id,
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            BailoutType type,
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            GetEntryMode mode) {
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_GE(id, 0);
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (id >= kMaxNumberOfEntries) return NULL;
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == ENSURE_ENTRY_CODE) {
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EnsureCodeForDeoptimizationEntry(isolate, type, id);
557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_EQ(mode, CALCULATE_ENTRY_ADDRESS);
559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeoptimizerData* data = isolate->deoptimizer_data();
5613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CHECK_LE(type, kLastBailoutType);
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* base = data->deopt_entry_code_[type];
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return base->area_start() + (id * table_entry_size_);
564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Deoptimizer::GetDeoptimizationId(Isolate* isolate,
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Address addr,
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     BailoutType type) {
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeoptimizerData* data = isolate->deoptimizer_data();
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* base = data->deopt_entry_code_[type];
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address start = base->area_start();
573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (addr < start ||
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addr >= start + (kMaxNumberOfEntries * table_entry_size_)) {
575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return kNotDeoptimizationEntry;
576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(0,
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            static_cast<int>(addr - start) % table_entry_size_);
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<int>(addr - start) / table_entry_size_;
580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5839fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockint Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               BailoutId id,
5859fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                               SharedFunctionInfo* shared) {
586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // TODO(kasperl): For now, we do a simple linear search for the PC
587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // offset associated with the given node id. This should probably be
588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // changed to a binary search.
589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = data->DeoptPoints();
590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < length; i++) {
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (data->AstId(i) == id) {
592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return data->PcAndState(i)->value();
593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OFStream os(stderr);
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os << "[couldn't find pc offset for node=" << id.ToInt() << "]\n"
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     << "[method: " << shared->DebugName()->ToCString().get() << "]\n"
598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier     << "[source:\n" << SourceCodeOf(shared) << "\n]" << std::endl;
599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  shared->GetHeap()->isolate()->PushStackTraceAndDie(0xfefefefe, data, shared,
601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                     0xfefefeff);
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("unable to find pc offset during deoptimization");
603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return -1;
604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
60744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) {
608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = 0;
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Count all entries in the deoptimizing code list of every context.
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = isolate->heap()->native_contexts_list();
61113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (!context->IsUndefined(isolate)) {
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Context* native_context = Context::cast(context);
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* element = native_context->DeoptimizedCodeListHead();
61413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    while (!element->IsUndefined(isolate)) {
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Code* code = Code::cast(element);
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      length++;
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      element = code->next_code_link();
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
620bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    context = Context::cast(context)->next_context_link();
621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return length;
623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
625109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace {
626109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
627109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochint LookupCatchHandler(TranslatedFrame* translated_frame, int* data_out) {
628109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  switch (translated_frame->kind()) {
629109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case TranslatedFrame::kFunction: {
630109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      BailoutId node_id = translated_frame->node_id();
631109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      JSFunction* function =
632109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          JSFunction::cast(translated_frame->begin()->GetRawValue());
633109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Code* non_optimized_code = function->shared()->code();
634109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FixedArray* raw_data = non_optimized_code->deoptimization_data();
635109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
636109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      unsigned pc_and_state =
637109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          Deoptimizer::GetOutputInfo(data, node_id, function->shared());
638109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
639109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HandlerTable* table =
640109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          HandlerTable::cast(non_optimized_code->handler_table());
641109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HandlerTable::CatchPrediction prediction;
642109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return table->LookupRange(pc_offset, data_out, &prediction);
643109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
644109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case TranslatedFrame::kInterpretedFunction: {
645109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int bytecode_offset = translated_frame->node_id().ToInt();
646109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      JSFunction* function =
647109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          JSFunction::cast(translated_frame->begin()->GetRawValue());
648109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      BytecodeArray* bytecode = function->shared()->bytecode_array();
649109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HandlerTable* table = HandlerTable::cast(bytecode->handler_table());
650109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HandlerTable::CatchPrediction prediction;
651109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return table->LookupRange(bytecode_offset, data_out, &prediction);
652109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
653109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    default:
654109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
655109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
656109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return -1;
657109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
658109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
659109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}  // namespace
660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// We rely on this function not causing a GC.  It is called from generated code
6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// without having a real stack frame in place.
663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DoComputeOutputFrames() {
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::ElapsedTimer timer;
665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Determine basic deoptimization information.  The optimized frame is
667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // described by the input data.
668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizationInputData* input_data =
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DeoptimizationInputData::cast(compiled_code_->deoptimization_data());
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  {
6723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Read caller's PC, caller's FP and caller's constant pool values
6733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // from input frame. Compute caller's frame top address.
6743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Register fp_reg = JavaScriptFrame::fp_register();
6763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    stack_fp_ = input_->GetRegister(fp_reg.code());
6773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    caller_frame_top_ = stack_fp_ + ComputeInputFrameAboveFpFixedSize();
6793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Address fp_address = input_->GetFramePointerAddress();
6813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    caller_fp_ = Memory::intptr_at(fp_address);
6823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    caller_pc_ =
6833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Memory::intptr_at(fp_address + CommonFrameConstants::kCallerPCOffset);
6843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    input_frame_context_ = Memory::intptr_at(
6853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        fp_address + CommonFrameConstants::kContextOrFrameTypeOffset);
6863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (FLAG_enable_embedded_constant_pool) {
6883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      caller_constant_pool_ = Memory::intptr_at(
6893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          fp_address + CommonFrameConstants::kConstantPoolOffset);
6903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
6913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
6923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    timer.Start();
695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ",
696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           MessageFor(bailout_type_));
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintFunctionName();
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
6993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           " (opt #%d) @%d, FP to SP delta: %d, caller sp: 0x%08" V8PRIxPTR
7003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           "]\n",
7013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           input_data->OptimizationId()->value(), bailout_id_, fp_to_sp_delta_,
7023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           caller_frame_top_);
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (bailout_type_ == EAGER || bailout_type_ == SOFT ||
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (compiled_code_->is_hydrogen_stub())) {
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      compiled_code_->PrintDeoptLocation(trace_scope_->file(), from_);
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId node_id = input_data->AstId(bailout_id_);
710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ByteArray* translations = input_data->TranslationByteArray();
711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned translation_index =
712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      input_data->TranslationIndex(bailout_id_)->value();
713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslationIterator state_iterator(translations, translation_index);
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  translated_state_.Init(
716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      input_->GetFramePointerAddress(), &state_iterator,
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      input_data->LiteralArray(), input_->GetRegisterValues(),
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      trace_scope_ == nullptr ? nullptr : trace_scope_->file());
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
720b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Do the input frame to output frame(s) translation.
721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t count = translated_state_.frames().size();
722109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If we are supposed to go to the catch handler, find the catching frame
723109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // for the catch and make sure we only deoptimize upto that frame.
724109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (deoptimizing_throw_) {
725109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    size_t catch_handler_frame_index = count;
726109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (size_t i = count; i-- > 0;) {
727109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      catch_handler_pc_offset_ = LookupCatchHandler(
728109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          &(translated_state_.frames()[i]), &catch_handler_data_);
729109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (catch_handler_pc_offset_ >= 0) {
730109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        catch_handler_frame_index = i;
731109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        break;
732109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
733109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
734109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK_LT(catch_handler_frame_index, count);
735109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    count = catch_handler_frame_index + 1;
736109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
737109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(output_ == NULL);
739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  output_ = new FrameDescription*[count];
740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < count; ++i) {
741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    output_[i] = NULL;
742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_count_ = static_cast<int>(count);
744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Translate each output frame.
7463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int frame_index = 0;  // output_frame_index
7473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (size_t i = 0; i < count; ++i, ++frame_index) {
7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Read the ast node id, function, and frame height for this output frame.
7493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TranslatedFrame* translated_frame = &(translated_state_.frames()[i]);
7503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    switch (translated_frame->kind()) {
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kFunction:
7523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DoComputeJSFrame(translated_frame, frame_index,
7533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                         deoptimizing_throw_ && i == count - 1);
7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        jsframe_count_++;
7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kInterpretedFunction:
7573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DoComputeInterpretedFrame(translated_frame, frame_index,
758109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                  deoptimizing_throw_ && i == count - 1);
759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        jsframe_count_++;
760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kArgumentsAdaptor:
7623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DoComputeArgumentsAdaptorFrame(translated_frame, frame_index);
7633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        break;
7643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case TranslatedFrame::kTailCallerFunction:
7653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DoComputeTailCallerFrame(translated_frame, frame_index);
7663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // Tail caller frame translations do not produce output frames.
7673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        frame_index--;
7683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        output_count_--;
7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kConstructStub:
7713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DoComputeConstructStubFrame(translated_frame, frame_index);
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kGetter:
7743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DoComputeAccessorStubFrame(translated_frame, frame_index, false);
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kSetter:
7773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DoComputeAccessorStubFrame(translated_frame, frame_index, true);
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kCompiledStub:
7803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DoComputeCompiledStubFrame(translated_frame, frame_index);
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case TranslatedFrame::kInvalid:
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FATAL("invalid frame");
7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Print some helpful diagnostic information.
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double ms = timer.Elapsed().InMillisecondsF();
791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int index = output_count_ - 1;  // Index of the topmost frame.
792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF(trace_scope_->file(), "[deoptimizing (%s): end ",
793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           MessageFor(bailout_type_));
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintFunctionName();
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
7963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           " @%d => node=%d, pc=0x%08" V8PRIxPTR ", caller sp=0x%08" V8PRIxPTR
7973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           ", state=%s, took %0.3f ms]\n",
7983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           bailout_id_, node_id.ToInt(), output_[index]->GetPc(),
799bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           caller_frame_top_, BailoutStateToString(static_cast<BailoutState>(
800bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  output_[index]->GetState()->value())),
801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           ms);
802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame,
8063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                   int frame_index, bool goto_catch_handler) {
807109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  SharedFunctionInfo* shared = translated_frame->raw_shared_info();
808109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
810109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool is_bottommost = (0 == frame_index);
811109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool is_topmost = (output_count_ - 1 == frame_index);
812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId node_id = translated_frame->node_id();
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height =
816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translated_frame->height() - 1;  // Do not count the context.
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
818109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
819109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Take the stack height from the handler table.
820109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    height = catch_handler_data_;
821109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // We also make space for the exception itself.
822109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    height_in_bytes = (height + 1) * kPointerSize;
823109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK(is_topmost);
824109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
825109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "  translating frame ");
831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    std::unique_ptr<char[]> name = shared->DebugName()->ToCString();
832109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PrintF(trace_scope_->file(), "%s", name.get());
833109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(),
834109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           height_in_bytes, goto_catch_handler ? " (throw)" : "");
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The 'fixed' part of the frame consists of the incoming parameters and
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the part described by JavaScriptFrameConstants.
839109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared);
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
843109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count = shared->internal_formal_parameter_count() + 1;
844109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FrameDescription* output_frame = new (output_frame_size)
845109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FrameDescription(output_frame_size, parameter_count);
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(frame_index >= 0 && frame_index < output_count_);
849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NULL(output_[frame_index]);
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The top address of the frame is computed from the previous frame's top and
8533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // this frame's size.
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address;
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_bottommost) {
8563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    top_address = caller_frame_top_ - output_frame_size;
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the incoming parameter translation.
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
870f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (trace_scope_ != nullptr) {
871f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    PrintF(trace_scope_->file(), "    -------------------------\n");
872f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
873f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There are no translation commands for the caller's pc and fp, the
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // context, and the function.  Synthesize their values and set them up
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // explicitly.
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The caller's pc for the bottommost output frame is the same as in the
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // input frame.  For all subsequent output frames, it can be read from the
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // previous one.  This frame's pc can be computed from the non-optimized
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // function code and AST id of the bailout.
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value;
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_bottommost) {
8853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = caller_pc_;
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetPc();
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, value);
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The caller's frame pointer for the bottommost output frame is the same
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // as in the input frame.  For all subsequent output frames, it can be
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // read from the previous one.  Also compute and set this frame's frame
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // pointer.
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_bottommost) {
8983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = caller_fp_;
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetFp();
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
9053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
9063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Register fp_reg = JavaScriptFrame::fp_register();
9073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_frame->SetRegister(fp_reg.code(), fp_value);
9083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // For the bottommost output frame the constant pool pointer can be gotten
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // from the input frame. For subsequent output frames, it can be read from
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the previous frame.
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_bottommost) {
9173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      value = caller_constant_pool_;
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value = output_[frame_index - 1]->GetConstantPool();
9208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For the bottommost output frame the context can be gotten from the input
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame. For all subsequent output frames it can be gotten from the function
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // so long as we don't inline functions that need local contexts.
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
930109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
931109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // When deoptimizing into a catch block, we need to take the context
932109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // from just above the top of the operand stack (we push the context
933109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // at the entry of the try block).
934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  TranslatedFrame::iterator context_pos = value_iterator;
935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int context_input_index = input_index;
936109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
937109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (unsigned i = 0; i < height + 1; ++i) {
938109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      context_pos++;
939109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      context_input_index++;
940109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
941109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read the context from the translations.
943109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Object* context = context_pos->GetRawValue();
94413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (context->IsUndefined(isolate_)) {
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the context was optimized away, just use the context from
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the activation. This should only apply to Crankshaft code.
947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!compiled_code_->is_turbofanned());
9483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_)
9493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                            : function->context();
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(context);
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetContext(value);
953109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteValueToOutput(context, context_input_index, frame_index, output_offset,
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "context    ");
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (context == isolate_->heap()->arguments_marker()) {
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address =
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        output_offset;
959109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    values_to_materialize_.push_back({output_address, context_pos});
960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The function was mentioned explicitly in the BEGIN_FRAME.
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(function);
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
969f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (trace_scope_ != nullptr) {
970f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    PrintF(trace_scope_->file(), "    -------------------------\n");
971f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
972f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Translate the rest of the frame.
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (unsigned i = 0; i < height; ++i) {
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Write out the exception for the catch handler.
981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    output_offset -= kPointerSize;
982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Object* exception_obj = reinterpret_cast<Object*>(
983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        input_->GetRegister(FullCodeGenerator::result_register().code()));
984109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    WriteValueToOutput(exception_obj, input_index, frame_index, output_offset,
985109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                       "exception   ");
986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    input_index++;
987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_offset);
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update constant pool.
991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Code* non_optimized_code = shared->code();
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(non_optimized_code->constant_pool());
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_topmost) {
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Register constant_pool_reg =
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          JavaScriptFrame::constant_pool_pointer_register();
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
10023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1003c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Compute this frame's PC and state.
1004109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FixedArray* raw_data = non_optimized_code->deoptimization_data();
1005109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
1006109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Address start = non_optimized_code->instruction_start();
1007109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
1008109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned pc_offset = goto_catch_handler
1009109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           ? catch_handler_pc_offset_
1010109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           : FullCodeGenerator::PcField::decode(pc_and_state);
1011109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
1012109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_frame->SetPc(pc_value);
1013109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1014109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If we are going to the catch handler, then the exception lives in
1015109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // the accumulator.
1016bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BailoutState state =
1017bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      goto_catch_handler
1018bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          ? BailoutState::TOS_REGISTER
1019bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          : FullCodeGenerator::BailoutStateField::decode(pc_and_state);
1020bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  output_frame->SetState(Smi::FromInt(static_cast<int>(state)));
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1022f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Clear the context register. The context might be a de-materialized object
1023f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // and will be materialized by {Runtime_NotifyDeoptimized}. For additional
1024f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // safety we use Smi(0) instead of the potential {arguments_marker} here.
1025f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_topmost) {
1026c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
1027f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Register context_reg = JavaScriptFrame::context_register();
1028f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    output_frame->SetRegister(context_reg.code(), context_value);
1029f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1030f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set the continuation for the topmost frame.
10323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Builtins* builtins = isolate_->builtins();
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (bailout_type_ == LAZY) {
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (bailout_type_ == SOFT) {
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK_EQ(bailout_type_, EAGER);
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetContinuation(
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(continuation->entry()));
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
10463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
10483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                            int frame_index,
1049109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                            bool goto_catch_handler) {
1050109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  SharedFunctionInfo* shared = translated_frame->raw_shared_info();
1051109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1053f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_bottommost = (0 == frame_index);
1054f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_topmost = (output_count_ - 1 == frame_index);
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1057109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int bytecode_offset = translated_frame->node_id().ToInt();
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = translated_frame->height();
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height_in_bytes = height * kPointerSize;
1060f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1061f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // All tranlations for interpreted frames contain the accumulator and hence
1062f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // are assumed to be in bailout state {BailoutState::TOS_REGISTER}. However
1063f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // such a state is only supported for the topmost frame. We need to skip
1064f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // pushing the accumulator for any non-topmost frame.
1065f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!is_topmost) height_in_bytes -= kPointerSize;
1066f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != NULL) {
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "  translating interpreted frame ");
1072f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    std::unique_ptr<char[]> name = shared->DebugName()->ToCString();
1073109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PrintF(trace_scope_->file(), "%s", name.get());
1074109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d%s\n",
1075109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           bytecode_offset, height_in_bytes,
1076109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           goto_catch_handler ? " (throw)" : "");
1077109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1078109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
1079109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    bytecode_offset = catch_handler_pc_offset_;
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The 'fixed' part of the frame consists of the incoming parameters and
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the part described by InterpreterFrameConstants.
1084109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared);
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate and store the output frame description.
1088109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count = shared->internal_formal_parameter_count() + 1;
1089109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FrameDescription* output_frame = new (output_frame_size)
1090109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FrameDescription(output_frame_size, parameter_count);
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetFrameType(StackFrame::INTERPRETED);
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(frame_index >= 0 && frame_index < output_count_);
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NULL(output_[frame_index]);
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_[frame_index] = output_frame;
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
10973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The top address of the frame is computed from the previous frame's top and
10983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // this frame's size.
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t top_address;
1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_bottommost) {
11013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    top_address = caller_frame_top_ - output_frame_size;
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetTop(top_address);
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Compute the incoming parameter translation.
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned output_offset = output_frame_size;
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < parameter_count; ++i) {
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_offset -= kPointerSize;
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (trace_scope_ != nullptr) {
1116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    PrintF(trace_scope_->file(), "    -------------------------\n");
1117f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // There are no translation commands for the caller's pc and fp, the
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // context, the function, new.target and the bytecode offset.  Synthesize
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // their values and set them up
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // explicitly.
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The caller's pc for the bottommost output frame is the same as in the
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // input frame.  For all subsequent output frames, it can be read from the
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // previous one.  This frame's pc can be computed from the non-optimized
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // function code and AST id of the bailout.
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPCOnStackSize;
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t value;
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_bottommost) {
11313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = caller_pc_;
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = output_[frame_index - 1]->GetPc();
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetCallerPc(output_offset, value);
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The caller's frame pointer for the bottommost output frame is the same
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // as in the input frame.  For all subsequent output frames, it can be
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // read from the previous one.  Also compute and set this frame's frame
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointer.
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kFPOnStackSize;
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_bottommost) {
11443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = caller_fp_;
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = output_[frame_index - 1]->GetFp();
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetCallerFp(output_offset, value);
1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t fp_value = top_address + output_offset;
1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetFp(fp_value);
11513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
11523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Register fp_reg = InterpretedFrame::fp_register();
11533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_frame->SetRegister(fp_reg.code(), fp_value);
11543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // For the bottommost output frame the constant pool pointer can be gotten
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // from the input frame. For subsequent output frames, it can be read from
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // the previous frame.
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_offset -= kPointerSize;
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_bottommost) {
11633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      value = caller_constant_pool_;
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value = output_[frame_index - 1]->GetConstantPool();
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // For the bottommost output frame the context can be gotten from the input
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // frame. For all subsequent output frames it can be gotten from the function
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // so long as we don't inline functions that need local contexts.
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // When deoptimizing into a catch block, we need to take the context
1178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // from a register that was specified in the handler table.
1179109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedFrame::iterator context_pos = value_iterator;
1180109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int context_input_index = input_index;
1181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (goto_catch_handler) {
1182109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Skip to the translated value of the register specified
1183109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // in the handler table.
1184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (int i = 0; i < catch_handler_data_ + 1; ++i) {
1185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      context_pos++;
1186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      context_input_index++;
1187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read the context from the translations.
1190109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Object* context = context_pos->GetRawValue();
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(context);
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_frame->SetContext(value);
1193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteValueToOutput(context, context_input_index, frame_index, output_offset,
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "context    ");
1195f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (context == isolate_->heap()->arguments_marker()) {
1196f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Address output_address =
1197f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
1198f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        output_offset;
1199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    values_to_materialize_.push_back({output_address, context_pos});
1200f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The function was mentioned explicitly in the BEGIN_FRAME.
1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value = reinterpret_cast<intptr_t>(function);
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // The new.target slot is only used during function activiation which is
1210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // before the first deopt point, so should never be needed. Just set it to
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // undefined.
1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* new_target = isolate_->heap()->undefined_value();
1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target  ");
1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1216109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Set the bytecode array pointer.
1217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_offset -= kPointerSize;
1218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Object* bytecode_array = shared->HasDebugInfo()
1219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               ? shared->GetDebugInfo()->DebugBytecodeArray()
1220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               : shared->bytecode_array();
1221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteValueToOutput(bytecode_array, 0, frame_index, output_offset,
1222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                     "bytecode array ");
1223109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The bytecode offset was mentioned explicitly in the BEGIN_FRAME.
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_offset -= kPointerSize;
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int raw_bytecode_offset =
1227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset;
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset);
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset,
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "bytecode offset ");
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (trace_scope_ != nullptr) {
1233f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    PrintF(trace_scope_->file(), "    -------------------------\n");
1234f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Translate the rest of the interpreter registers in the frame.
1237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (unsigned i = 0; i < height - 1; ++i) {
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_offset -= kPointerSize;
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Translate the accumulator register (depending on frame position).
1244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_topmost) {
1245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // For topmost frame, put the accumulator on the stack. The bailout state
1246f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // for interpreted frames is always set to {BailoutState::TOS_REGISTER} and
1247f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // the {NotifyDeoptimized} builtin pops it off the topmost frame (possibly
1248f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // after materialization).
1249f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    output_offset -= kPointerSize;
1250f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (goto_catch_handler) {
1251f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // If we are lazy deopting to a catch handler, we set the accumulator to
1252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // the exception (which lives in the result register).
1253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      intptr_t accumulator_value =
1254f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          input_->GetRegister(FullCodeGenerator::result_register().code());
1255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0,
1256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         frame_index, output_offset, "accumulator ");
1257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      value_iterator++;
1258f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
1259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   output_offset, "accumulator ");
1261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
1262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
1263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // For non-topmost frames, skip the accumulator translation. For those
1264f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // frames, the return value from the callee will become the accumulator.
1265f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    value_iterator++;
1266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    input_index++;
1267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK_EQ(0u, output_offset);
1269f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1270c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Compute this frame's PC and state. The PC will be a special builtin that
1271c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // continues the bytecode dispatch. Note that non-topmost and lazy-style
1272c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // bailout handlers also advance the bytecode offset before dispatch, hence
1273c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // simulating what normal handlers do upon completion of the operation.
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Builtins* builtins = isolate_->builtins();
1275109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Code* dispatch_builtin =
1276c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      (!is_topmost || (bailout_type_ == LAZY)) && !goto_catch_handler
1277c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          ? builtins->builtin(Builtins::kInterpreterEnterBytecodeAdvance)
1278c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          : builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
1279109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry()));
1280bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Restore accumulator (TOS) register.
1281bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  output_frame->SetState(
1282bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER)));
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Update constant pool.
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    intptr_t constant_pool_value =
1287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool());
1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetConstantPool(constant_pool_value);
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_topmost) {
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register constant_pool_reg =
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          InterpretedFrame::constant_pool_pointer_register();
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1296f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Clear the context register. The context might be a de-materialized object
1297f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // and will be materialized by {Runtime_NotifyDeoptimized}. For additional
1298f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // safety we use Smi(0) instead of the potential {arguments_marker} here.
1299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_topmost) {
1300c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
1301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Register context_reg = JavaScriptFrame::context_register();
1302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    output_frame->SetRegister(context_reg.code(), context_value);
1303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1304f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Set the continuation for the topmost frame.
13063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
1307bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (bailout_type_ == LAZY) {
1309bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (bailout_type_ == SOFT) {
1311bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK_EQ(bailout_type_, EAGER);
1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetContinuation(
1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<intptr_t>(continuation->entry()));
1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
13203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Deoptimizer::DoComputeArgumentsAdaptorFrame(
13213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TranslatedFrame* translated_frame, int frame_index) {
1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
13233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool is_bottommost = (0 == frame_index);
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = translated_frame->height();
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating arguments adaptor => height=%d\n", height_in_bytes);
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
13353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFixedFrameSize;
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
1340109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count = height;
1341109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FrameDescription* output_frame = new (output_frame_size)
1342109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FrameDescription(output_frame_size, parameter_count);
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Arguments adaptor can not be topmost.
13463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CHECK(frame_index < output_count_ - 1);
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(output_[frame_index] == NULL);
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The top address of the frame is computed from the previous frame's top and
13513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // this frame's size.
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address;
13533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_bottommost) {
13543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    top_address = caller_frame_top_ - output_frame_size;
13553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
13563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
13573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the incoming parameter translation.
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
13673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC from the previous frame.
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
13703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  intptr_t value;
13713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_bottommost) {
13723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = caller_pc_;
13733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
13743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = output_[frame_index - 1]->GetPc();
13753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
13763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  output_frame->SetCallerPc(output_offset, value);
13773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the previous frame, and set this frame's FP.
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
13813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_bottommost) {
13823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = caller_fp_;
13833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
13843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = output_[frame_index - 1]->GetFp();
13853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
13903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the previous frame.
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
13943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (is_bottommost) {
13953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      value = caller_constant_pool_;
13963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else {
13973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      value = output_[frame_index - 1]->GetConstantPool();
13983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
14023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A marker value is used in place of the context.
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t context = reinterpret_cast<intptr_t>(
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, context);
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(context, frame_index, output_offset,
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "context (adaptor sentinel)\n");
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(function);
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of incoming arguments.
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "argc ");
1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "(%d)\n", height - 1);
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(0 == output_offset);
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Builtins* builtins = isolate_->builtins();
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* adaptor_trampoline =
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc_value = reinterpret_cast<intptr_t>(
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      adaptor_trampoline->instruction_start() +
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(pc_value);
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool());
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
14403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
14413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Deoptimizer::DoComputeTailCallerFrame(TranslatedFrame* translated_frame,
14433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                           int frame_index) {
14443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  SharedFunctionInfo* shared = translated_frame->raw_shared_info();
14453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool is_bottommost = (0 == frame_index);
14473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Tail caller frame can't be topmost.
14483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CHECK_NE(output_count_ - 1, frame_index);
14493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (trace_scope_ != NULL) {
14513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    PrintF(trace_scope_->file(), "  translating tail caller frame ");
1452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    std::unique_ptr<char[]> name = shared->DebugName()->ToCString();
14533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    PrintF(trace_scope_->file(), "%s\n", name.get());
14543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
14553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!is_bottommost) return;
14573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Drop arguments adaptor frame below current frame if it exsits.
14593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Address fp_address = input_->GetFramePointerAddress();
14603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Address adaptor_fp_address =
14613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Memory::Address_at(fp_address + CommonFrameConstants::kCallerFPOffset);
14623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR) !=
14643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Memory::Object_at(adaptor_fp_address +
14653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                        CommonFrameConstants::kContextOrFrameTypeOffset)) {
14663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return;
14673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
14683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int caller_params_count =
14703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Smi::cast(
14713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          Memory::Object_at(adaptor_fp_address +
14723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                            ArgumentsAdaptorFrameConstants::kLengthOffset))
14733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          ->value();
14743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int callee_params_count =
14763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      function_->shared()->internal_formal_parameter_count();
14773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Both caller and callee parameters count do not include receiver.
14793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int offset = (caller_params_count - callee_params_count) * kPointerSize;
14803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  intptr_t new_stack_fp =
14813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      reinterpret_cast<intptr_t>(adaptor_fp_address) + offset;
14823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  intptr_t new_caller_frame_top = new_stack_fp +
14843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                  (callee_params_count + 1) * kPointerSize +
14853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                  CommonFrameConstants::kFixedFrameSizeAboveFp;
14863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  intptr_t adaptor_caller_pc = Memory::intptr_at(
14883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      adaptor_fp_address + CommonFrameConstants::kCallerPCOffset);
14893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  intptr_t adaptor_caller_fp = Memory::intptr_at(
14903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      adaptor_fp_address + CommonFrameConstants::kCallerFPOffset);
14913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (trace_scope_ != NULL) {
14933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    PrintF(trace_scope_->file(),
14943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           "    dropping caller arguments adaptor frame: offset=%d, "
14953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           "fp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR
14963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           ", "
14973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           "caller sp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR "\n",
14983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           offset, stack_fp_, new_stack_fp, caller_frame_top_,
14993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           new_caller_frame_top);
15003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
15013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  caller_frame_top_ = new_caller_frame_top;
15023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  caller_fp_ = adaptor_caller_fp;
15033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  caller_pc_ = adaptor_caller_pc;
15043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
15053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
15063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
15073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                              int frame_index) {
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
15093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool is_topmost = (output_count_ - 1 == frame_index);
15103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The construct frame could become topmost only if we inlined a constructor
15113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // call which does a tail call (otherwise the tail callee's frame would be
15123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // the topmost one). So it could only be the LAZY case.
15133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CHECK(!is_topmost || bailout_type_ == LAZY);
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Builtins* builtins = isolate_->builtins();
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = translated_frame->height();
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
15203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
15213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // If the construct frame appears to be topmost we should ensure that the
15223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // value of result register is preserved during continuation execution.
15233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // We do this here by "pushing" the result of the constructor function to the
15243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // top of the reconstructed stack and then using the
1525bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // BailoutState::TOS_REGISTER machinery.
15263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
15273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    height_in_bytes += kPointerSize;
15283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
15293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Skip function.
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating construct stub => height=%d\n", height_in_bytes);
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
15383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  unsigned fixed_frame_size = ConstructFrameConstants::kFixedFrameSize;
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameDescription* output_frame =
1543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (output_frame_size) FrameDescription(output_frame_size);
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::CONSTRUCT);
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Construct stub can not be topmost.
15473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(frame_index > 0 && frame_index < output_count_);
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(output_[frame_index] == NULL);
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The top address of the frame is computed from the previous frame's top and
15523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // this frame's size.
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address;
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the incoming parameter translation.
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int parameter_count = height;
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The allocated receiver of a construct stub frame is passed as the
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // receiver parameter through the translation. It might be encoding
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // a captured object, override the slot address for a captured object.
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &value_iterator, &input_index, frame_index, output_offset, nullptr,
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (i == 0) ? reinterpret_cast<Address>(top_address) : nullptr);
1568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC from the previous frame.
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, callers_pc);
1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
1575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the previous frame, and set this frame's FP.
1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = output_[frame_index - 1]->GetFp();
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
15823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
15833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Register fp_reg = JavaScriptFrame::fp_register();
15843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_frame->SetRegister(fp_reg.code(), fp_value);
15853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the previous frame.
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetConstantPool();
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // A marker value is used to mark the frame.
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset,
16023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                       "typed frame marker\n");
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The context can be gotten from the previous frame.
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
16063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  value = output_[frame_index - 1]->GetContext();
1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
16083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of incoming arguments.
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "argc ");
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "(%d)\n", height - 1);
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The newly allocated object was passed as receiver in the artificial
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // constructor stub environment created by HEnvironment::CopyForInlining().
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset,
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "allocated receiver\n");
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
16283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Ensure the result is restored back when we return to the stub.
16293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_offset -= kPointerSize;
16303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Register result_reg = FullCodeGenerator::result_register();
16313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = input_->GetRegister(result_reg.code());
16323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_frame->SetFrameSlot(output_offset, value);
16333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
16343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                         "constructor result\n");
16353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1636bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    output_frame->SetState(
1637bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER)));
16383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
16393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_offset);
1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc = reinterpret_cast<intptr_t>(
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      construct_stub->instruction_start() +
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->construct_stub_deopt_pc_offset()->value());
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(pc);
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(construct_stub->constant_pool());
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
16503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (is_topmost) {
16513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Register constant_pool_reg =
16523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          JavaScriptFrame::constant_pool_pointer_register();
16533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      output_frame->SetRegister(constant_pool_reg.code(), fp_value);
16543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Clear the context register. The context might be a de-materialized object
1658f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // and will be materialized by {Runtime_NotifyDeoptimized}. For additional
1659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // safety we use Smi(0) instead of the potential {arguments_marker} here.
1660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_topmost) {
1661c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
1662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Register context_reg = JavaScriptFrame::context_register();
1663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    output_frame->SetRegister(context_reg.code(), context_value);
1664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1665f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
16663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Set the continuation for the topmost frame.
16673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
16683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Builtins* builtins = isolate_->builtins();
16693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK_EQ(LAZY, bailout_type_);
16703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
16713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_frame->SetContinuation(
16723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        reinterpret_cast<intptr_t>(continuation->entry()));
16733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
16743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
16773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                             int frame_index,
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             bool is_setter_stub_frame) {
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
16803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool is_topmost = (output_count_ - 1 == frame_index);
16813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The accessor frame could become topmost only if we inlined an accessor
16823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // call which does a tail call (otherwise the tail callee's frame would be
16833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // the topmost one). So it could only be the LAZY case.
16843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CHECK(!is_topmost || bailout_type_ == LAZY);
1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1687109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Skip accessor.
1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The receiver (and the implicit return value, if any) are expected in
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // registers by the LoadIC/StoreIC, so they don't belong to the output stack
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frame. This means that we have to use a height of 0.
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height = 0;
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned height_in_bytes = height * kPointerSize;
16953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
16963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // If the accessor frame appears to be topmost we should ensure that the
16973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // value of result register is preserved during continuation execution.
16983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // We do this here by "pushing" the result of the accessor function to the
16993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // top of the reconstructed stack and then using the
1700bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // BailoutState::TOS_REGISTER machinery.
17013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // We don't need to restore the result in case of a setter call because we
17023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // have to return the stored value but not the result of the setter function.
17033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool should_preserve_result = is_topmost && !is_setter_stub_frame;
17043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (should_preserve_result) {
17053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    height_in_bytes += kPointerSize;
17063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
17073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* kind = is_setter_stub_frame ? "setter" : "getter";
1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating %s stub => height=%u\n", kind, height_in_bytes);
1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We need 1 stack entry for the return address and enough entries for the
17153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // StackFrame::INTERNAL (FP, frame type, context, code object and constant
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pool (if enabled)- see MacroAssembler::EnterFrame).
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For a setter stub frame we need one additional entry for the implicit
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // return value, see StoreStubCompiler::CompileStoreViaSetter.
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_entries =
1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (StandardFrameConstants::kFixedFrameSize / kPointerSize) + 1 +
1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (is_setter_stub_frame ? 1 : 0);
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and store the output frame description.
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameDescription* output_frame =
1727109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (output_frame_size) FrameDescription(output_frame_size);
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::INTERNAL);
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // A frame for an accessor stub can not be bottommost.
17313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CHECK(frame_index > 0 && frame_index < output_count_);
1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NULL(output_[frame_index]);
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The top address of the frame is computed from the previous frame's top and
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // this frame's size.
1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_offset = output_frame_size;
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's PC from the previous frame.
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPCOnStackSize;
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_offset, callers_pc);
1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the previous frame, and set this frame's FP.
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kFPOnStackSize;
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t value = output_[frame_index - 1]->GetFp();
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_offset, value);
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t fp_value = top_address + output_offset;
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(fp_value);
17543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
17553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Register fp_reg = JavaScriptFrame::fp_register();
17563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_frame->SetRegister(fp_reg.code(), fp_value);
17573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the previous frame.
1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = output_[frame_index - 1]->GetConstantPool();
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_offset, value);
1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Set the frame type.
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
17733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "frame type ");
1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "(%s sentinel)\n", kind);
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get Code object from accessor stub.
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_offset -= kPointerSize;
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Builtins::Name name = is_setter_stub_frame ?
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Builtins::kStoreIC_Setter_ForDeopt :
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Builtins::kLoadIC_Getter_ForDeopt;
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* accessor_stub = isolate_->builtins()->builtin(name);
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(accessor_stub);
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_offset, value);
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n");
1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The context can be gotten from the previous frame.
17893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  output_offset -= kPointerSize;
17903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  value = output_[frame_index - 1]->GetContext();
17913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  output_frame->SetFrameSlot(output_offset, value);
17923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
17933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Skip receiver.
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  value_iterator++;
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  input_index++;
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_setter_stub_frame) {
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The implicit return value was part of the artificial setter stub
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // environment.
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_offset -= kPointerSize;
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_offset);
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (should_preserve_result) {
18073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Ensure the result is restored back when we return to the stub.
18083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_offset -= kPointerSize;
18093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Register result_reg = FullCodeGenerator::result_register();
18103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = input_->GetRegister(result_reg.code());
18113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_frame->SetFrameSlot(output_offset, value);
18123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_offset,
18133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                         "accessor result\n");
18143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1815bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    output_frame->SetState(
1816bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER)));
18173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
1818bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    output_frame->SetState(
1819bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS)));
18203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
18213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_offset);
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Smi* offset = is_setter_stub_frame ?
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->setter_stub_deopt_pc_offset() :
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->getter_stub_deopt_pc_offset();
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc = reinterpret_cast<intptr_t>(
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      accessor_stub->instruction_start() + offset->value());
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(pc);
1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
18343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (is_topmost) {
18353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Register constant_pool_reg =
18363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          JavaScriptFrame::constant_pool_pointer_register();
18373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      output_frame->SetRegister(constant_pool_reg.code(), fp_value);
18383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1841f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Clear the context register. The context might be a de-materialized object
1842f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // and will be materialized by {Runtime_NotifyDeoptimized}. For additional
1843f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // safety we use Smi(0) instead of the potential {arguments_marker} here.
1844f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_topmost) {
1845c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
1846f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Register context_reg = JavaScriptFrame::context_register();
1847f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    output_frame->SetRegister(context_reg.code(), context_value);
1848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1849f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
18503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Set the continuation for the topmost frame.
18513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_topmost) {
18523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Builtins* builtins = isolate_->builtins();
18533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK_EQ(LAZY, bailout_type_);
18543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
18553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    output_frame->SetContinuation(
18563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        reinterpret_cast<intptr_t>(continuation->entry()));
18573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
18583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Deoptimizer::DoComputeCompiledStubFrame(TranslatedFrame* translated_frame,
18613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                             int frame_index) {
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //               FROM                                  TO
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |          ....           |          |          ....           |
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    +-------------------------+          +-------------------------+
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    | JSFunction continuation |          | JSFunction continuation |
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    +-------------------------+          +-------------------------+
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  |    saved frame (FP)     |          |    saved frame (FP)     |
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  +=========================+<-fpreg   +=========================+<-fpreg
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  |constant pool (if ool_cp)|          |constant pool (if ool_cp)|
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  +-------------------------+          +-------------------------|
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |  |   JSFunction context    |          |   JSFunction context    |
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // v  +-------------------------+          +-------------------------|
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |   COMPILED_STUB marker  |          |   STUB_FAILURE marker   |
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    +-------------------------+          +-------------------------+
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |                         |          |  caller args.arguments_ |
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    | ...                     |          +-------------------------+
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |                         |          |  caller args.length_    |
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    |-------------------------|<-spreg   +-------------------------+
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         |  caller args pointer    |
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         +-------------------------+
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         |  caller stack param 1   |
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //      parameters in registers            +-------------------------+
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //       and spilled to stack              |           ....          |
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         +-------------------------+
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         |  caller stack param n   |
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         +-------------------------+<-spreg
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = number of parameters
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = failure handler address
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = saved frame
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //                                         reg = JSFunction context
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Caller stack params contain the register parameters to the stub first,
1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // and then, if the descriptor specifies a constant number of stack
1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // parameters, the stack parameters as well.
1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame::iterator value_iterator = translated_frame->begin();
1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int input_index = 0;
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(compiled_code_->is_hydrogen_stub());
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int major_key = CodeStub::GetMajorKey(compiled_code_);
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeStubDescriptor descriptor(isolate_, compiled_code_->stub_key());
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The output frame must have room for all pushed register parameters
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and the standard stack frame slots.  Include space for an argument
1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // object to the callee and optionally the space to pass the argument
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // object to the stub failure handler.
1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int param_count = descriptor.GetRegisterParameterCount();
1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int stack_param_count = descriptor.GetStackParameterCount();
1910109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // The translated frame contains all of the register parameters
1911109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // plus the context.
1912109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK_EQ(translated_frame->height(), param_count + 1);
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_GE(param_count, 0);
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int height_in_bytes = kPointerSize * (param_count + stack_param_count);
19163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int fixed_frame_size = StubFailureTrampolineFrameConstants::kFixedFrameSize;
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int output_frame_size = height_in_bytes + fixed_frame_size;
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trace_scope_ != NULL) {
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF(trace_scope_->file(),
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           "  translating %s => StubFailureTrampolineStub, height=%d\n",
1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           CodeStub::MajorName(static_cast<CodeStub::Major>(major_key)),
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           height_in_bytes);
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The stub failure trampoline is a single frame.
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameDescription* output_frame =
1927109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (output_frame_size) FrameDescription(output_frame_size);
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_EQ(frame_index, 0);
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_[frame_index] = output_frame;
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The top address of the frame is computed from the previous frame's top and
19333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // this frame's size.
19343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  intptr_t top_address = caller_frame_top_ - output_frame_size;
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetTop(top_address);
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Set caller's PC (JSFunction continuation).
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned output_frame_offset = output_frame_size - kFPOnStackSize;
19393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  intptr_t value = caller_pc_;
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerPc(output_frame_offset, value);
1941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "caller's pc\n");
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read caller's FP from the input frame, and set this frame's FP.
19453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  value = caller_fp_;
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kFPOnStackSize;
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetCallerFp(output_frame_offset, value);
19483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  intptr_t frame_ptr = top_address + output_frame_offset;
19493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register fp_reg = StubFailureTrampolineFrame::fp_register();
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetRegister(fp_reg.code(), frame_ptr);
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFp(frame_ptr);
1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "caller's fp\n");
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the caller's constant pool from the input frame.
19573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    value = caller_constant_pool_;
1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame_offset -= kPointerSize;
1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetCallerConstantPool(output_frame_offset, value);
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "caller's constant_pool\n");
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The marker for the typed stack frame
1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = reinterpret_cast<intptr_t>(
1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE));
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_frame_offset, value);
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset,
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       "function (stub failure sentinel)\n");
1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t caller_arg_count = stack_param_count;
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool arg_count_known = !descriptor.stack_parameter_count().is_valid();
1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Build the Arguments object for the caller's parameters and a pointer to it.
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int args_arguments_offset = output_frame_offset;
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t the_hole = reinterpret_cast<intptr_t>(
1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->heap()->the_hole_value());
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (arg_count_known) {
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (caller_arg_count - 1) * kPointerSize;
1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = the_hole;
1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(args_arguments_offset, value);
1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(
1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value, frame_index, args_arguments_offset,
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arg_count_known ? "args.arguments\n" : "args.arguments (the hole)\n");
1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int length_frame_offset = output_frame_offset;
1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = arg_count_known ? caller_arg_count : the_hole;
1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(length_frame_offset, value);
1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(
1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value, frame_index, length_frame_offset,
1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arg_count_known ? "args.length\n" : "args.length (the hole)\n");
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame_offset -= kPointerSize;
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value = frame_ptr + StandardFrameConstants::kCallerSPOffset -
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (output_frame_size - output_frame_offset) + kPointerSize;
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetFrameSlot(output_frame_offset, value);
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DebugPrintOutputSlot(value, frame_index, output_frame_offset, "args*\n");
2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy the register parameters to the failure frame.
2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int arguments_length_offset = -1;
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < param_count; ++i) {
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame_offset -= kPointerSize;
2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WriteTranslatedValueToOutput(&value_iterator, &input_index, 0,
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 output_frame_offset);
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!arg_count_known &&
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        descriptor.GetRegisterParameter(i)
2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            .is(descriptor.stack_parameter_count())) {
2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arguments_length_offset = output_frame_offset;
2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2020109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Object* maybe_context = value_iterator->GetRawValue();
2021109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK(maybe_context->IsContext());
2022109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Register context_reg = StubFailureTrampolineFrame::context_register();
2023109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  value = reinterpret_cast<intptr_t>(maybe_context);
2024109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  output_frame->SetRegister(context_reg.code(), value);
2025109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ++value_iterator;
2026109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy constant stack parameters to the failure frame. If the number of stack
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // parameters is not known in the descriptor, the arguments object is the way
2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to access them.
2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < stack_param_count; i++) {
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame_offset -= kPointerSize;
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object** stack_parameter = reinterpret_cast<Object**>(
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_ptr + StandardFrameConstants::kCallerSPOffset +
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (stack_param_count - i - 1) * kPointerSize);
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = reinterpret_cast<intptr_t>(*stack_parameter);
2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    output_frame->SetFrameSlot(output_frame_offset, value);
2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, output_frame_offset,
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "stack parameter\n");
2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, output_frame_offset);
2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!arg_count_known) {
2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK_GE(arguments_length_offset, 0);
2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We know it's a smi because 1) the code stub guarantees the stack
2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // parameter count is in smi range, and 2) the DoTranslateCommand in the
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // parameter loop above translated that to a tagged value.
2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Smi* smi_caller_arg_count = reinterpret_cast<Smi*>(
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        output_frame->GetFrameSlot(arguments_length_offset));
2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    caller_arg_count = smi_caller_arg_count->value();
2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetFrameSlot(length_frame_offset, caller_arg_count);
2052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(caller_arg_count, frame_index, length_frame_offset,
2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "args.length\n");
2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (caller_arg_count - 1) * kPointerSize;
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetFrameSlot(args_arguments_offset, value);
2057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(value, frame_index, args_arguments_offset,
2058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "args.arguments");
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy the double registers from the input into the output frame.
2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CopyDoubleRegisters(output_frame);
2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fill registers containing handler and number of parameters.
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetPlatformCompiledStubRegisters(output_frame, &descriptor);
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute this frame's PC, state, and continuation.
2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* trampoline = NULL;
2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StubFunctionMode function_mode = descriptor.function_mode();
2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StubFailureTrampolineStub(isolate_, function_mode)
2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      .FindCodeInCache(&trampoline);
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(trampoline != NULL);
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetPc(reinterpret_cast<intptr_t>(
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      trampoline->instruction_start()));
2075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register constant_pool_reg =
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        StubFailureTrampolineFrame::constant_pool_pointer_register();
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t constant_pool_value =
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(trampoline->constant_pool());
2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetConstantPool(constant_pool_value);
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2083bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  output_frame->SetState(
2084bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS)));
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* notify_failure =
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles);
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  output_frame->SetContinuation(
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<intptr_t>(notify_failure->entry()));
2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Walk to the last JavaScript output frame to find out if it has
2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // adapted arguments.
2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) {
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (frame_index != 0) it->Advance();
2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
20983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  translated_state_.Prepare(it->frame()->has_adapted_arguments(),
20993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                            reinterpret_cast<Address>(stack_fp_));
2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& materialization : values_to_materialize_) {
2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> value = materialization.value_->GetValue();
2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (trace_scope_ != nullptr) {
2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF("Materialization [0x%08" V8PRIxPTR "] <- 0x%08" V8PRIxPTR " ;  ",
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             reinterpret_cast<intptr_t>(materialization.output_slot_address_),
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             reinterpret_cast<intptr_t>(*value));
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value->ShortPrint(trace_scope_->file());
2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF(trace_scope_->file(), "\n");
2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *(reinterpret_cast<intptr_t*>(materialization.output_slot_address_)) =
2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<intptr_t>(*value);
2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
21163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  isolate_->materialized_object_store()->Remove(
21173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      reinterpret_cast<Address>(stack_fp_));
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::WriteTranslatedValueToOutput(
2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame::iterator* iterator, int* input_index, int frame_index,
2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned output_offset, const char* debug_hint_string,
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address_for_materialization) {
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* value = (*iterator)->GetRawValue();
2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteValueToOutput(value, *input_index, frame_index, output_offset,
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     debug_hint_string);
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value == isolate_->heap()->arguments_marker()) {
2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address =
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        output_offset;
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output_address_for_materialization == nullptr) {
2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_address_for_materialization = output_address;
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values_to_materialize_.push_back(
2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        {output_address_for_materialization, *iterator});
2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (*iterator)++;
2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (*input_index)++;
2143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::WriteValueToOutput(Object* value, int input_index,
2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     int frame_index, unsigned output_offset,
2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     const char* debug_hint_string) {
2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  output_[frame_index]->SetFrameSlot(output_offset,
2150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     reinterpret_cast<intptr_t>(value));
2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DebugPrintOutputSlot(reinterpret_cast<intptr_t>(value), frame_index,
2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         output_offset, debug_hint_string);
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value->ShortPrint(trace_scope_->file());
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(), "  (input #%d)\n", input_index);
2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::DebugPrintOutputSlot(intptr_t value, int frame_index,
2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       unsigned output_offset,
2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       const char* debug_hint_string) {
2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (trace_scope_ != nullptr) {
2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address output_address =
2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        output_offset;
2168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF(trace_scope_->file(),
2169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ;  %s",
2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           reinterpret_cast<intptr_t>(output_address), output_offset, value,
2171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           debug_hint_string == nullptr ? "" : debug_hint_string);
2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
21753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochunsigned Deoptimizer::ComputeInputFrameAboveFpFixedSize() const {
21763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  unsigned fixed_size = CommonFrameConstants::kFixedFrameSizeAboveFp;
2177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!function_->IsSmi()) {
2178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    fixed_size += ComputeIncomingArgumentSize(function_->shared());
2179109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
21803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return fixed_size;
21813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
21823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
21833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochunsigned Deoptimizer::ComputeInputFrameSize() const {
2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The fp-to-sp delta already takes the context, constant pool pointer and the
2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // function into account so we have to avoid double counting them.
21863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  unsigned fixed_size_above_fp = ComputeInputFrameAboveFpFixedSize();
21873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  unsigned result = fixed_size_above_fp + fp_to_sp_delta_;
2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned stack_slots = compiled_code_->stack_slots();
2190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned outgoing_size =
2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ComputeOutgoingArgumentSize(compiled_code_, bailout_id_);
21923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CHECK_EQ(fixed_size_above_fp + (stack_slots * kPointerSize) -
21933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                 CommonFrameConstants::kFixedFrameSizeAboveFp + outgoing_size,
21943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             result);
2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// static
2200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochunsigned Deoptimizer::ComputeJavascriptFixedSize(SharedFunctionInfo* shared) {
2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The fixed part of the frame consists of the return address, frame
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointer, function, context, and all the incoming arguments.
2203109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return ComputeIncomingArgumentSize(shared) +
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         StandardFrameConstants::kFixedFrameSize;
2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2207109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// static
2208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochunsigned Deoptimizer::ComputeInterpretedFixedSize(SharedFunctionInfo* shared) {
2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The fixed part of the frame consists of the return address, frame
2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointer, function, context, new.target, bytecode offset and all the
2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // incoming arguments.
2212109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return ComputeIncomingArgumentSize(shared) +
2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         InterpreterFrameConstants::kFixedFrameSize;
2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2216109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// static
2217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochunsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo* shared) {
2218109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return (shared->internal_formal_parameter_count() + 1) * kPointerSize;
2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochunsigned Deoptimizer::ComputeOutgoingArgumentSize(Code* code,
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                  unsigned bailout_id) {
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizationInputData* data =
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DeoptimizationInputData::cast(code->deoptimization_data());
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned height = data->ArgumentsStackHeight(bailout_id)->value();
2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return height * kPointerSize;
2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   BailoutType type,
2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   int max_entry_id) {
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We cannot run this if the serializer is enabled because this will
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // cause us to emit relocation information for the external
2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // references. This is fine because the deoptimizer's code section
2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // isn't meant to be serialized at all.
2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(type == EAGER || type == SOFT || type == LAZY);
2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizerData* data = isolate->deoptimizer_data();
2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int entry_count = data->deopt_entry_code_entries_[type];
2241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (max_entry_id < entry_count) return;
2242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries);
2243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (max_entry_id >= entry_count) entry_count *= 2;
2244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(entry_count <= Deoptimizer::kMaxNumberOfEntries);
2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler masm(isolate, NULL, 16 * KB, CodeObjectRequired::kYes);
2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm.set_emit_debug_code(false);
2248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenerateDeoptimizationEntries(&masm, entry_count, type);
2249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CodeDesc desc;
2250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm.GetCode(&desc);
2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!RelocInfo::RequiresRelocation(desc));
2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MemoryChunk* chunk = data->deopt_entry_code_[type];
2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
2255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        desc.instr_size);
2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!chunk->CommitArea(desc.instr_size)) {
2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    V8::FatalProcessOutOfMemory(
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        "Deoptimizer::EnsureCodeForDeoptimizationEntry");
2259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CopyBytes(chunk->area_start(), desc.buffer,
2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            static_cast<size_t>(desc.instr_size));
2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::FlushICache(isolate, chunk->area_start(), desc.instr_size);
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data->deopt_entry_code_entries_[type] = entry_count;
2265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochFrameDescription::FrameDescription(uint32_t frame_size, int parameter_count)
2268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    : frame_size_(frame_size),
2269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      parameter_count_(parameter_count),
2270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      top_(kZapUint32),
2271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      pc_(kZapUint32),
22723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      fp_(kZapUint32),
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      context_(kZapUint32),
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      constant_pool_(kZapUint32) {
2275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Zap all the registers.
2276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int r = 0; r < Register::kNumRegisters; r++) {
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(jbramley): It isn't safe to use kZapUint32 here. If the register
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // isn't used before the next safepoint, the GC will try to scan it as a
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // tagged value. kZapUint32 looks like a valid tagged pointer, but it isn't.
2280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetRegister(r, kZapUint32);
2281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Zap all the slots.
2284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (unsigned o = 0; o < frame_size; o += kPointerSize) {
2285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFrameSlot(o, kZapUint32);
2286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2289c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid TranslationBuffer::Add(int32_t value) {
2290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This wouldn't handle kMinInt correctly if it ever encountered it.
2291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(value != kMinInt);
2292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Encode the sign bit in the least significant bit.
2293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_negative = (value < 0);
2294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t bits = ((is_negative ? -value : value) << 1) |
2295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<int32_t>(is_negative);
2296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Encode the individual bytes using the least significant bit of
2297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // each byte to indicate whether or not more bytes follow.
2298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  do {
2299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uint32_t next = bits >> 7;
2300c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    contents_.push_back(((bits << 1) & 0xFF) | (next != 0));
2301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bits = next;
2302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } while (bits != 0);
2303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint32_t TranslationIterator::Next() {
2307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Run through the bytes until we reach one with a least significant
2308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // bit of zero (marks the end).
2309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t bits = 0;
2310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; true; i += 7) {
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasNext());
2312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uint8_t next = buffer_->get(index_++);
2313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bits |= (next >> 1) << i;
2314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if ((next & 1) == 0) break;
2315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The bits encode the sign in the least significant bit.
2317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_negative = (bits & 1) == 1;
2318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t result = bits >> 1;
2319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return is_negative ? -result : result;
2320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) {
2324c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<ByteArray> result = factory->NewByteArray(CurrentIndex(), TENURED);
2325c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  contents_.CopyTo(result->GetDataStartAddress());
2326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
2327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
23303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Translation::BeginConstructStubFrame(int literal_id, unsigned height) {
2331c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(CONSTRUCT_STUB_FRAME);
2332c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(literal_id);
2333c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(height);
2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginGetterStubFrame(int literal_id) {
2338c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(GETTER_STUB_FRAME);
2339c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(literal_id);
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginSetterStubFrame(int literal_id) {
2344c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(SETTER_STUB_FRAME);
2345c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(literal_id);
23463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
23473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
23483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
23493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) {
2350c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(ARGUMENTS_ADAPTOR_FRAME);
2351c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(literal_id);
2352c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(height);
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Translation::BeginTailCallerFrame(int literal_id) {
2356c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(TAIL_CALLER_FRAME);
2357c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(literal_id);
23583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginJSFrame(BailoutId node_id,
2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int literal_id,
2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               unsigned height) {
2363c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(JS_FRAME);
2364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(node_id.ToInt());
2365c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(literal_id);
2366c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(height);
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::BeginInterpretedFrame(BailoutId bytecode_offset,
2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        int literal_id, unsigned height) {
2372c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(INTERPRETED_FRAME);
2373c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(bytecode_offset.ToInt());
2374c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(literal_id);
2375c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(height);
2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::BeginCompiledStubFrame(int height) {
2380c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(COMPILED_STUB_FRAME);
2381c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(height);
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginArgumentsObject(int args_length) {
2386c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(ARGUMENTS_OBJECT);
2387c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(args_length);
23883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
23893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
23903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::BeginCapturedObject(int length) {
2392c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(CAPTURED_OBJECT);
2393c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(length);
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::DuplicateObject(int object_index) {
2398c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(DUPLICATED_OBJECT);
2399c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(object_index);
2400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreRegister(Register reg) {
2404c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(REGISTER);
2405c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(reg.code());
2406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32Register(Register reg) {
2410c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(INT32_REGISTER);
2411c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(reg.code());
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreUint32Register(Register reg) {
2416c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(UINT32_REGISTER);
2417c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(reg.code());
2418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::StoreBoolRegister(Register reg) {
2422c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(BOOL_REGISTER);
2423c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(reg.code());
2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
242613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Translation::StoreFloatRegister(FloatRegister reg) {
2427c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(FLOAT_REGISTER);
2428c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(reg.code());
242913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreDoubleRegister(DoubleRegister reg) {
2432c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(DOUBLE_REGISTER);
2433c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(reg.code());
2434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreStackSlot(int index) {
2438c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(STACK_SLOT);
2439c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(index);
2440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32StackSlot(int index) {
2444c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(INT32_STACK_SLOT);
2445c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(index);
2446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreUint32StackSlot(int index) {
2450c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(UINT32_STACK_SLOT);
2451c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(index);
2452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::StoreBoolStackSlot(int index) {
2456c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(BOOL_STACK_SLOT);
2457c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(index);
2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
246013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Translation::StoreFloatStackSlot(int index) {
2461c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(FLOAT_STACK_SLOT);
2462c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(index);
246313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreDoubleStackSlot(int index) {
2466c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(DOUBLE_STACK_SLOT);
2467c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(index);
2468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreLiteral(int literal_id) {
2472c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(LITERAL);
2473c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(literal_id);
2474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Translation::StoreArgumentsObject(bool args_known,
2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       int args_index,
2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       int args_length) {
2480c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(ARGUMENTS_OBJECT);
2481c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(args_known);
2482c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(args_index);
2483c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  buffer_->Add(args_length);
2484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
2485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Translation::StoreJSFrameFunction() {
2488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  StoreStackSlot((StandardFrameConstants::kCallerPCOffset -
24893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  StandardFrameConstants::kFunctionOffset) /
2490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                 kPointerSize);
2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint Translation::NumberOfOperandsFor(Opcode opcode) {
2494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  switch (opcode) {
2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case GETTER_STUB_FRAME:
2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SETTER_STUB_FRAME:
2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DUPLICATED_OBJECT:
2498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case ARGUMENTS_OBJECT:
2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CAPTURED_OBJECT:
2500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case REGISTER:
2501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_REGISTER:
2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case UINT32_REGISTER:
2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BOOL_REGISTER:
250413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case FLOAT_REGISTER:
2505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_REGISTER:
2506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case STACK_SLOT:
2507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_STACK_SLOT:
2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case UINT32_STACK_SLOT:
2509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BOOL_STACK_SLOT:
251013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case FLOAT_STACK_SLOT:
2511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_STACK_SLOT:
2512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case LITERAL:
2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case COMPILED_STUB_FRAME:
25143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case TAIL_CALLER_FRAME:
2515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return 1;
25163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case BEGIN:
25173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case ARGUMENTS_ADAPTOR_FRAME:
25183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case CONSTRUCT_STUB_FRAME:
25193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return 2;
25203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case JS_FRAME:
2521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case INTERPRETED_FRAME:
2522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return 3;
2523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FATAL("Unexpected translation type");
2525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
2530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* Translation::StringFor(Opcode opcode) {
2532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define TRANSLATION_OPCODE_CASE(item)   case item: return #item;
2533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (opcode) {
2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRANSLATION_OPCODE_LIST(TRANSLATION_OPCODE_CASE)
2535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef TRANSLATION_OPCODE_CASE
2537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
2538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return "";
2539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
2542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<FixedArray> MaterializedObjectStore::Get(Address fp) {
2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = StackIdToIndex(fp);
2546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index == -1) {
2547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Handle<FixedArray>::null();
2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> array = GetStackEntries();
2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_GT(array->length(), index);
2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<FixedArray>::cast(Handle<Object>(array->get(index), isolate()));
2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MaterializedObjectStore::Set(Address fp,
2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  Handle<FixedArray> materialized_objects) {
2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = StackIdToIndex(fp);
2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index == -1) {
2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    index = frame_fps_.length();
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frame_fps_.Add(fp);
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> array = EnsureStackEntries(index + 1);
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array->set(index, *materialized_objects);
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool MaterializedObjectStore::Remove(Address fp) {
2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = StackIdToIndex(fp);
2570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index == -1) {
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_GE(index, 0);
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame_fps_.Remove(index);
2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* array = isolate()->heap()->materialized_objects();
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_LT(index, array->length());
2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = index; i < frame_fps_.length(); i++) {
2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    array->set(i, array->get(i + 1));
2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array->set(frame_fps_.length(), isolate()->heap()->undefined_value());
2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
2583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint MaterializedObjectStore::StackIdToIndex(Address fp) {
2587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < frame_fps_.length(); i++) {
2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (frame_fps_[i] == fp) {
2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return i;
2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
2593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<FixedArray> MaterializedObjectStore::GetStackEntries() {
2597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<FixedArray>(isolate()->heap()->materialized_objects());
2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<FixedArray> MaterializedObjectStore::EnsureStackEntries(int length) {
2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> array = GetStackEntries();
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (array->length() >= length) {
2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return array;
2605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_length = length > 10 ? length : 10;
2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_length < 2 * array->length()) {
2609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_length = 2 * array->length();
2610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> new_array =
2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->factory()->NewFixedArray(new_length, TENURED);
2614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < array->length(); i++) {
2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_array->set(i, array->get(i));
2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = array->length(); i < length; i++) {
2618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_array->set(i, isolate()->heap()->undefined_value());
2619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate()->heap()->SetRootMaterializedObjects(*new_array);
2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new_array;
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2624109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace {
2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2626109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochHandle<Object> GetValueForDebugger(TranslatedFrame::iterator it,
2627109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                   Isolate* isolate) {
2628109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (it->GetRawValue() == isolate->heap()->arguments_marker()) {
2629109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!it->IsMaterializableByDebugger()) {
2630109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return isolate->factory()->undefined_value();
2631f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    }
2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2633109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return it->GetValue();
2634109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
26358389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2636109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}  // namespace
2637109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2638109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochDeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state,
2639109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                           TranslatedState::iterator frame_it,
2640109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                           Isolate* isolate) {
2641109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If the previous frame is an adaptor frame, we will take the parameters
2642109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // from there.
2643109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedState::iterator parameter_frame = frame_it;
2644109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (parameter_frame != state->begin()) {
2645109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_frame--;
26468389745919cae02139ddc085a63c00d024269cf2Ben Murdoch  }
2647109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int parameter_count;
2648109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (parameter_frame->kind() == TranslatedFrame::kArgumentsAdaptor) {
2649109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_count = parameter_frame->height() - 1;  // Ignore the receiver.
2650109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
2651109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_frame = frame_it;
2652109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_count =
2653109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        frame_it->shared_info()->internal_formal_parameter_count();
2654109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2655109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedFrame::iterator parameter_it = parameter_frame->begin();
2656109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  parameter_it++;  // Skip the function.
2657109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  parameter_it++;  // Skip the receiver.
26588389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2659109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Figure out whether there is a construct stub frame on top of
2660109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // the parameter frame.
2661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  has_construct_stub_ =
2662109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      parameter_frame != state->begin() &&
2663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      (parameter_frame - 1)->kind() == TranslatedFrame::kConstructStub;
26648389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
2665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
2666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    source_position_ = Deoptimizer::ComputeSourcePositionFromBytecodeArray(
2667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        *frame_it->shared_info(), frame_it->node_id());
2668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_EQ(TranslatedFrame::kFunction, frame_it->kind());
2670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    source_position_ = Deoptimizer::ComputeSourcePositionFromBaselineCode(
2671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        *frame_it->shared_info(), frame_it->node_id());
2672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2673109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2674109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedFrame::iterator value_it = frame_it->begin();
2675109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get the function. Note that this might materialize the function.
2676109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // In case the debugger mutates this value, we should deoptimize
2677109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // the function and remember the value in the materialized value store.
2678109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  function_ = Handle<JSFunction>::cast(value_it->GetValue());
2679109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2680109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  parameters_.resize(static_cast<size_t>(parameter_count));
2681109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < parameter_count; i++) {
2682109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Handle<Object> parameter = GetValueForDebugger(parameter_it, isolate);
2683109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    SetParameter(i, parameter);
2684109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    parameter_it++;
2685109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2686109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2687109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Skip the function, the receiver and the arguments.
2688109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int skip_count =
2689109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      frame_it->shared_info()->internal_formal_parameter_count() + 2;
2690109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TranslatedFrame::iterator stack_it = frame_it->begin();
2691109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < skip_count; i++) {
2692109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    stack_it++;
2693109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2694109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2695109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get the context.
2696109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  context_ = GetValueForDebugger(stack_it, isolate);
2697109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  stack_it++;
2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2699109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get the expression stack.
2700109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int stack_height = frame_it->height();
2701109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (frame_it->kind() == TranslatedFrame::kFunction ||
2702109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
2703109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // For full-code frames, we should not count the context.
2704109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // For interpreter frames, we should not count the accumulator.
2705109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // TODO(jarin): Clean up the indexing in translated frames.
2706109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    stack_height--;
2707109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  expression_stack_.resize(static_cast<size_t>(stack_height));
2709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < stack_height; i++) {
2710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Handle<Object> expression = GetValueForDebugger(stack_it, isolate);
2711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    SetExpression(i, expression);
2712109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    stack_it++;
2713109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2715109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // For interpreter frame, skip the accumulator.
2716109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
2717109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    stack_it++;
2718109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2719109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK(stack_it == frame_it->end());
2720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDeoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, Address pc) {
2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePosition last_position = SourcePosition::Unknown();
2725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeReason last_reason = DeoptimizeReason::kNoReason;
2726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int last_deopt_id = kNoDeoptimizationId;
2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int mask = RelocInfo::ModeMask(RelocInfo::DEOPT_REASON) |
2728bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             RelocInfo::ModeMask(RelocInfo::DEOPT_ID) |
2729c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch             RelocInfo::ModeMask(RelocInfo::DEOPT_SCRIPT_OFFSET) |
2730c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch             RelocInfo::ModeMask(RelocInfo::DEOPT_INLINING_ID);
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (RelocIterator it(code, mask); !it.done(); it.next()) {
2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RelocInfo* info = it.rinfo();
2733bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (info->pc() >= pc) {
2734bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return DeoptInfo(last_position, last_reason, last_deopt_id);
2735bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
2736c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (info->rmode() == RelocInfo::DEOPT_SCRIPT_OFFSET) {
2737c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int script_offset = static_cast<int>(info->data());
2738c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      it.next();
2739c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK(it.rinfo()->rmode() == RelocInfo::DEOPT_INLINING_ID);
2740c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int inlining_id = static_cast<int>(it.rinfo()->data());
2741c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      last_position = SourcePosition(script_offset, inlining_id);
2742bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    } else if (info->rmode() == RelocInfo::DEOPT_ID) {
2743bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      last_deopt_id = static_cast<int>(info->data());
2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (info->rmode() == RelocInfo::DEOPT_REASON) {
2745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      last_reason = static_cast<DeoptimizeReason>(info->data());
2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return DeoptInfo(SourcePosition::Unknown(), DeoptimizeReason::kNoReason, -1);
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint Deoptimizer::ComputeSourcePositionFromBaselineCode(
2754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    SharedFunctionInfo* shared, BailoutId node_id) {
2755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(shared->HasBaselineCode());
2756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Code* code = shared->code();
2757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FixedArray* raw_data = code->deoptimization_data();
2758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
2759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, shared);
2760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int code_offset =
2761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      static_cast<int>(FullCodeGenerator::PcField::decode(pc_and_state));
2762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return AbstractCode::cast(code)->SourcePosition(code_offset);
2763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
2764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
2766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint Deoptimizer::ComputeSourcePositionFromBytecodeArray(
2767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    SharedFunctionInfo* shared, BailoutId node_id) {
2768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(shared->HasBytecodeArray());
2769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return AbstractCode::cast(shared->bytecode_array())
2770c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      ->SourcePosition(node_id.ToInt());
2771bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
2772bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// static
2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container,
2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int length,
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int object_index) {
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kArgumentsObject);
2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.materialization_info_ = {object_index, length};
2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container,
2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   int length,
2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   int object_index) {
2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kCapturedObject);
2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.materialization_info_ = {object_index, length};
2789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewDuplicateObject(TranslatedState* container,
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int id) {
2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kDuplicatedObject);
2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.materialization_info_ = {id, -1};
2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
280313e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochTranslatedValue TranslatedValue::NewFloat(TranslatedState* container,
280413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                          float value) {
280513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  TranslatedValue slot(container, kFloat);
280613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  slot.float_value_ = value;
280713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return slot;
280813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
280913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
281013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// static
2811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewDouble(TranslatedState* container,
2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           double value) {
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kDouble);
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.double_value_ = value;
2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewInt32(TranslatedState* container,
2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          int32_t value) {
2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kInt32);
2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.int32_value_ = value;
2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewUInt32(TranslatedState* container,
2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           uint32_t value) {
2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kUInt32);
2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.uint32_value_ = value;
2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewBool(TranslatedState* container,
2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         uint32_t value) {
2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kBoolBit);
2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.uint32_value_ = value;
2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewTagged(TranslatedState* container,
2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           Object* literal) {
2849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue slot(container, kTagged);
2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  slot.raw_literal_ = literal;
2851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return slot;
2852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedValue::NewInvalid(TranslatedState* container) {
2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedValue(container, kInvalid);
2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochIsolate* TranslatedValue::isolate() const { return container_->isolate(); }
2862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* TranslatedValue::raw_literal() const {
2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kTagged, kind());
2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return raw_literal_;
2867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint32_t TranslatedValue::int32_value() const {
2871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kInt32, kind());
2872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return int32_value_;
2873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochuint32_t TranslatedValue::uint32_value() const {
2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind() == kUInt32 || kind() == kBoolBit);
2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return uint32_value_;
2879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
288113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochfloat TranslatedValue::float_value() const {
288213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_EQ(kFloat, kind());
288313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return float_value_;
288413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble TranslatedValue::double_value() const {
2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kDouble, kind());
2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return double_value_;
2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedValue::object_length() const {
2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind() == kArgumentsObject || kind() == kCapturedObject);
2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return materialization_info_.length_;
2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedValue::object_index() const {
2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind() == kArgumentsObject || kind() == kCapturedObject ||
2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         kind() == kDuplicatedObject);
2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return materialization_info_.id_;
2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* TranslatedValue::GetRawValue() const {
2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we have a value, return it.
2907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> result_handle;
2908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value_.ToHandle(&result_handle)) {
2909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return *result_handle;
2910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Otherwise, do a best effort to get the value without allocation.
2913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kTagged:
2915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return raw_literal();
2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInt32: {
2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_smi = Smi::IsValid(int32_value());
2919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (is_smi) {
2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Smi::FromInt(int32_value());
2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUInt32: {
2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_smi = (uint32_value() <= static_cast<uintptr_t>(Smi::kMaxValue));
2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (is_smi) {
2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Smi::FromInt(static_cast<int32_t>(uint32_value()));
2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kBoolBit: {
2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (uint32_value() == 0) {
2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate()->heap()->false_value();
2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        CHECK_EQ(1U, uint32_value());
2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate()->heap()->true_value();
2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we could not get the value without allocation, return the arguments
2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // marker.
2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return isolate()->heap()->arguments_marker();
2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> TranslatedValue::GetValue() {
2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> result;
2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we already have a value, then get it.
2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value_.ToHandle(&result)) return result;
2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Otherwise we have to materialize.
2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kTagged:
2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInt32:
2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kUInt32:
2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kBoolBit:
296313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case TranslatedValue::kFloat:
2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDouble: {
2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MaterializeSimple();
2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return value_.ToHandleChecked();
2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kArgumentsObject:
2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kCapturedObject:
2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDuplicatedObject:
2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return container_->MaterializeObjectAt(object_index());
2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInvalid:
2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FATAL("unexpected case");
2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Handle<Object>::null();
2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FATAL("internal error: value missing");
2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<Object>::null();
2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedValue::MaterializeSimple() {
2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we already have materialized, return.
2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!value_.is_null()) return;
2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* raw_value = GetRawValue();
2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (raw_value != isolate()->heap()->arguments_marker()) {
2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We can get the value without allocation, just return it here.
2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ = Handle<Object>(raw_value, isolate());
2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInt32: {
2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(int32_value()));
2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUInt32:
3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(uint32_value()));
3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
300513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kFloat:
300613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(float_value()));
300713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return;
300813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDouble:
3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_ = Handle<Object>(isolate()->factory()->NewNumber(double_value()));
3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCapturedObject:
3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDuplicatedObject:
3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArgumentsObject:
3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInvalid:
3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kTagged:
3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kBoolBit:
3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FATAL("internal error: unexpected materialization.");
3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool TranslatedValue::IsMaterializedObject() const {
3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCapturedObject:
3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDuplicatedObject:
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArgumentsObject:
3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3036109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool TranslatedValue::IsMaterializableByDebugger() const {
3037109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // At the moment, we only allow materialization of doubles.
3038109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return (kind() == kDouble);
3039109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedValue::GetChildrenCount() const {
3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kind() == kCapturedObject || kind() == kArgumentsObject) {
3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return object_length();
3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return 0;
3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochuint32_t TranslatedState::GetUInt32Slot(Address fp, int slot_offset) {
3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address address = fp + slot_offset;
3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_BIG_ENDIAN && V8_HOST_ARCH_64_BIT
3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::uint32_at(address + kIntSize);
3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else
3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::uint32_at(address);
3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedValue::Handlify() {
3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kind() == kTagged) {
3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ = Handle<Object>(raw_literal(), isolate());
3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    raw_literal_ = nullptr;
3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id,
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         SharedFunctionInfo* shared_info,
3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         int height) {
3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info,
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        height);
3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame.node_id_ = node_id;
3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return frame;
3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::InterpretedFrame(
3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BailoutId bytecode_offset, SharedFunctionInfo* shared_info, int height) {
3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame frame(kInterpretedFunction, shared_info->GetIsolate(),
3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        shared_info, height);
3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame.node_id_ = bytecode_offset;
3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return frame;
3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::AccessorFrame(
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Kind kind, SharedFunctionInfo* shared_info) {
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kind == kSetter || kind == kGetter);
3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info);
3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame(
3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SharedFunctionInfo* shared_info, int height) {
3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(),
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         shared_info, height);
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
31003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochTranslatedFrame TranslatedFrame::TailCallerFrame(
31013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    SharedFunctionInfo* shared_info) {
31023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return TranslatedFrame(kTailCallerFunction, shared_info->GetIsolate(),
31033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                         shared_info, 0);
31043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedFrame::ConstructStubFrame(
3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SharedFunctionInfo* shared_info, int height) {
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info,
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         height);
3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TranslatedFrame::GetValueCount() {
3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (kind()) {
3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFunction: {
3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int parameter_count =
3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          raw_shared_info_->internal_formal_parameter_count() + 1;
3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // + 1 for function.
3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return height_ + parameter_count + 1;
3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInterpretedFunction: {
3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int parameter_count =
3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          raw_shared_info_->internal_formal_parameter_count() + 1;
3125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // + 2 for function and context.
3126109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return height_ + parameter_count + 2;
3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kGetter:
3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;  // Function and receiver.
3131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSetter:
3133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 3;  // Function, receiver and the value to set.
3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArgumentsAdaptor:
3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kConstructStub:
3137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 1 + height_;
3138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
31393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kTailCallerFunction:
31403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return 1;  // Function.
31413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCompiledStub:
3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return height_;
3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInvalid:
3146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
3147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
3150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedFrame::Handlify() {
3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (raw_shared_info_ != nullptr) {
3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    shared_info_ = Handle<SharedFunctionInfo>(raw_shared_info_);
3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    raw_shared_info_ = nullptr;
3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& value : values_) {
3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value.Handlify();
3161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame TranslatedState::CreateNextTranslatedFrame(
3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslationIterator* iterator, FixedArray* literal_array, Address fp,
3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FILE* trace_file) {
3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode opcode =
3169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (opcode) {
3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::JS_FRAME: {
3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BailoutId node_id = BailoutId(iterator->Next());
3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading input frame %s", name.get());
3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int arg_count = shared_info->internal_formal_parameter_count() + 1;
3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n",
3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               node_id.ToInt(), arg_count, height);
3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::JSFrame(node_id, shared_info, height);
3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INTERPRETED_FRAME: {
3187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BailoutId bytecode_offset = BailoutId(iterator->Next());
3188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
3193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading input frame %s", name.get());
3194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int arg_count = shared_info->internal_formal_parameter_count() + 1;
3195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file,
3196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               " => bytecode_offset=%d, args=%d, height=%d; inputs:\n",
3197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               bytecode_offset.ToInt(), arg_count, height);
3198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::InterpretedFrame(bytecode_offset, shared_info,
3200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               height);
3201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::ARGUMENTS_ADAPTOR_FRAME: {
3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
3209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading arguments adaptor frame %s", name.get());
3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, " => height=%d; inputs:\n", height);
3211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height);
3213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
32153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case Translation::TAIL_CALLER_FRAME: {
32163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      SharedFunctionInfo* shared_info =
32173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
32183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (trace_file != nullptr) {
3219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
32203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        PrintF(trace_file, "  reading tail caller frame marker %s\n",
32213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch               name.get());
32223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
32233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return TranslatedFrame::TailCallerFrame(shared_info);
32243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
32253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::CONSTRUCT_STUB_FRAME: {
3227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
3232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading construct stub frame %s", name.get());
3233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, " => height=%d; inputs:\n", height);
3234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::ConstructStubFrame(shared_info, height);
3236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::GETTER_STUB_FRAME: {
3239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading getter frame %s; inputs:\n", name.get());
3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter,
3246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            shared_info);
3247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::SETTER_STUB_FRAME: {
3250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* shared_info =
3251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
3252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
3254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "  reading setter frame %s; inputs:\n", name.get());
3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::AccessorFrame(TranslatedFrame::kSetter,
3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            shared_info);
3258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::COMPILED_STUB_FRAME: {
3261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int height = iterator->Next();
3262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file,
3264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               "  reading compiler stub frame => height=%d; inputs:\n", height);
3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedFrame::CompiledStubFrame(height,
3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                literal_array->GetIsolate());
3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BEGIN:
3271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DUPLICATED_OBJECT:
3272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::ARGUMENTS_OBJECT:
3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::CAPTURED_OBJECT:
3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::REGISTER:
3275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INT32_REGISTER:
3276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::UINT32_REGISTER:
3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_REGISTER:
327813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case Translation::FLOAT_REGISTER:
3279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DOUBLE_REGISTER:
3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::STACK_SLOT:
3281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INT32_STACK_SLOT:
3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::UINT32_STACK_SLOT:
3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_STACK_SLOT:
328413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case Translation::FLOAT_STACK_SLOT:
3285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DOUBLE_STACK_SLOT:
3286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::LITERAL:
3287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
3288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FATAL("We should never get here - unexpected deopt info.");
3290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedFrame::InvalidFrame();
3291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
3292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
3295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedFrame::AdvanceIterator(
3296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    std::deque<TranslatedValue>::iterator* iter) {
3297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int values_to_skip = 1;
3298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (values_to_skip > 0) {
3299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Consume the current element.
3300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values_to_skip--;
3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Add all the children.
3302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    values_to_skip += (*iter)->GetChildrenCount();
3303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    (*iter)++;
3305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
3307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
33098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// We can't intermix stack decoding and allocations because
33108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// deoptimization infrastracture is not GC safe.
33118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Thus we build a temporary structure in malloced space.
3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedValue TranslatedState::CreateNextTranslatedValue(
3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int frame_index, int value_index, TranslationIterator* iterator,
3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedArray* literal_array, Address fp, RegisterValues* registers,
3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FILE* trace_file) {
3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  disasm::NameConverter converter;
3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode opcode =
3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
33208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  switch (opcode) {
33218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::BEGIN:
33223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case Translation::JS_FRAME:
3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INTERPRETED_FRAME:
33243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case Translation::ARGUMENTS_ADAPTOR_FRAME:
33253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case Translation::TAIL_CALLER_FRAME:
33263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case Translation::CONSTRUCT_STUB_FRAME:
3327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::GETTER_STUB_FRAME:
3328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::SETTER_STUB_FRAME:
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::COMPILED_STUB_FRAME:
33308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      // Peeled off before getting here.
33318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      break;
33328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::DUPLICATED_OBJECT: {
3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_id = iterator->Next();
3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "duplicated object #%d", object_id);
3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_positions_.push_back(object_positions_[object_id]);
3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDuplicateObject(this, object_id);
3340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::ARGUMENTS_OBJECT: {
3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int arg_count = iterator->Next();
3344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_index = static_cast<int>(object_positions_.size());
3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "argumets object #%d (length = %d)", object_index,
3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               arg_count);
3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_positions_.push_back({frame_index, value_index});
3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewArgumentsObject(this, arg_count, object_index);
3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::CAPTURED_OBJECT: {
3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int field_count = iterator->Next();
3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_index = static_cast<int>(object_positions_.size());
3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "captured object #%d (length = %d)", object_index,
3358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               field_count);
3359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_positions_.push_back({frame_index, value_index});
3361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDeferredObject(this, field_count,
3362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                object_index);
3363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
33648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::REGISTER: {
3366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; %s ", value,
3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
3375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::INT32_REGISTER: {
3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%" V8PRIdPTR " ; %s ", value,
3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewInt32(this, static_cast<int32_t>(value));
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::UINT32_REGISTER: {
3389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%" V8PRIuPTR " ; %s (uint)", value,
3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value));
3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_REGISTER: {
3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = registers->GetRegister(input_reg);
3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%" V8PRIdPTR " ; %s (bool)", value,
3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter.NameOfCPURegister(input_reg));
3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewBool(this, static_cast<uint32_t>(value));
3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
341113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case Translation::FLOAT_REGISTER: {
341213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      int input_reg = iterator->Next();
341313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
341413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      float value = registers->GetFloatRegister(input_reg);
341513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (trace_file != nullptr) {
341613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        PrintF(trace_file, "%e ; %s (float)", value,
341713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch               RegisterConfiguration::Crankshaft()->GetFloatRegisterName(
341813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                   input_reg));
341913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
342013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return TranslatedValue::NewFloat(this, value);
342113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
342213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::DOUBLE_REGISTER: {
3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_reg = iterator->Next();
3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (registers == nullptr) return TranslatedValue::NewInvalid(this);
3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      double value = registers->GetDoubleRegister(input_reg);
3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
342813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        PrintF(trace_file, "%e ; %s (double)", value,
342913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch               RegisterConfiguration::Crankshaft()->GetDoubleRegisterName(
343013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                   input_reg));
3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDouble(this, value);
3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
34348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
34358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::STACK_SLOT: {
3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset));
3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; [fp %c %d] ", value,
3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
34458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
34468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
34478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::INT32_STACK_SLOT: {
3448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t value = GetUInt32Slot(fp, slot_offset);
3451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%d ; (int) [fp %c %d] ",
3453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               static_cast<int32_t>(value), slot_offset < 0 ? '-' : '+',
3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               std::abs(slot_offset));
3455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewInt32(this, value);
34578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
34588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Translation::UINT32_STACK_SLOT: {
3460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t value = GetUInt32Slot(fp, slot_offset);
3463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value,
3465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewUInt32(this, value);
3468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case Translation::BOOL_STACK_SLOT: {
3471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t value = GetUInt32Slot(fp, slot_offset);
3474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value,
3476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewBool(this, value);
3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case Translation::FLOAT_STACK_SLOT: {
348213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      int slot_offset =
348313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
348413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      float value = ReadFloatValue(fp + slot_offset);
348513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (trace_file != nullptr) {
348613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        PrintF(trace_file, "%e ; (float) [fp %c %d] ", value,
348713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
348813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
348913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return TranslatedValue::NewFloat(this, value);
349013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
349113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
34928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::DOUBLE_STACK_SLOT: {
3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int slot_offset =
3494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
3495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      double value = ReadDoubleValue(fp + slot_offset);
3496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "%e ; (double) [fp %c %d] ", value,
3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewDouble(this, value);
35018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
35028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
35038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    case Translation::LITERAL: {
35048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      int literal_index = iterator->Next();
3505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Object* value = literal_array->get(literal_index);
3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ",
3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               reinterpret_cast<intptr_t>(value), literal_index);
3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return TranslatedValue::NewTagged(this, value);
35138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
35148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
35158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("We should never get here - unexpected deopt info.");
3517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TranslatedValue(nullptr, TranslatedValue::kInvalid);
35188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
35198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
35208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedState::TranslatedState(JavaScriptFrame* frame)
3522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : isolate_(nullptr),
3523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      stack_frame_pointer_(nullptr),
3524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_adapted_arguments_(false) {
3525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int deopt_index = Safepoint::kNoDeoptimizationIndex;
35268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  DeoptimizationInputData* data =
35278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
3528bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(data != nullptr && deopt_index != Safepoint::kNoDeoptimizationIndex);
35298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  TranslationIterator it(data->TranslationByteArray(),
35308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                         data->TranslationIndex(deopt_index)->value());
3531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Init(frame->fp(), &it, data->LiteralArray(), nullptr /* registers */,
3532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       nullptr /* trace file */);
3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedState::TranslatedState()
3537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : isolate_(nullptr),
3538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      stack_frame_pointer_(nullptr),
3539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_adapted_arguments_(false) {}
3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::Init(Address input_frame_pointer,
3543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           TranslationIterator* iterator,
3544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           FixedArray* literal_array, RegisterValues* registers,
3545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           FILE* trace_file) {
3546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(frames_.empty());
3547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate_ = literal_array->GetIsolate();
3549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read out the 'header' translation.
3550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode opcode =
3551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
3552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(opcode == Translation::BEGIN);
3553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int count = iterator->Next();
3555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  iterator->Next();  // Drop JS frames count.
3556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frames_.reserve(count);
3558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::stack<int> nested_counts;
3560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read the frames
3562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < count; i++) {
3563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Read the frame descriptor.
3564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frames_.push_back(CreateNextTranslatedFrame(
3565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        iterator, literal_array, input_frame_pointer, trace_file));
3566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame& frame = frames_.back();
3567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Read the values.
3569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int values_to_process = frame.GetValueCount();
3570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (values_to_process > 0 || !nested_counts.empty()) {
3571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (nested_counts.empty()) {
3573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // For top level values, print the value number.
3574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintF(trace_file, "    %3i: ",
3575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 frame.GetValueCount() - values_to_process);
3576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // Take care of indenting for nested values.
3578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintF(trace_file, "         ");
3579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          for (size_t j = 0; j < nested_counts.size(); j++) {
3580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintF(trace_file, "  ");
3581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedValue value = CreateNextTranslatedValue(
3586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          i, static_cast<int>(frame.values_.size()), iterator, literal_array,
3587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          input_frame_pointer, registers, trace_file);
3588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame.Add(value);
3589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (trace_file != nullptr) {
3591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintF(trace_file, "\n");
3592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
35933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Update the value count and resolve the nesting.
3595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      values_to_process--;
3596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int children_count = value.GetChildrenCount();
3597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (children_count > 0) {
3598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        nested_counts.push(values_to_process);
3599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        values_to_process = children_count;
3600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        while (values_to_process == 0 && !nested_counts.empty()) {
3602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          values_to_process = nested_counts.top();
3603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          nested_counts.pop();
3604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
36078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
3608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(!iterator->HasNext() ||
3610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        static_cast<Translation::Opcode>(iterator->Next()) ==
3611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Translation::BEGIN);
3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
36138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::Prepare(bool has_adapted_arguments,
3616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              Address stack_frame_pointer) {
3617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& frame : frames_) frame.Handlify();
3618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  stack_frame_pointer_ = stack_frame_pointer;
3620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  has_adapted_arguments_ = has_adapted_arguments;
3621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UpdateFromPreviouslyMaterializedObjects();
3623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> TranslatedState::MaterializeAt(int frame_index,
3627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              int* value_index) {
3628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedFrame* frame = &(frames_[frame_index]);
3629109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK(static_cast<size_t>(*value_index) < frame->values_.size());
3630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedValue* slot = &(frame->values_[*value_index]);
3632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (*value_index)++;
3633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (slot->kind()) {
3635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kTagged:
3636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInt32:
3637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kUInt32:
3638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kBoolBit:
363913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case TranslatedValue::kFloat:
3640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDouble: {
3641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot->MaterializeSimple();
3642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> value = slot->GetValue();
3643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (value->IsMutableHeapNumber()) {
3644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        HeapNumber::cast(*value)->set_map(isolate()->heap()->heap_number_map());
3645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return value;
3647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kArgumentsObject: {
3650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int length = slot->GetChildrenCount();
3651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<JSObject> arguments;
3652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (GetAdaptedArguments(&arguments, frame_index)) {
3653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Store the materialized object and consume the nested values.
3654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (int i = 0; i < length; ++i) {
3655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          MaterializeAt(frame_index, value_index);
3656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSFunction> function =
3659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<JSFunction>::cast(frame->front().GetValue());
3660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        arguments = isolate_->factory()->NewArgumentsObject(function, length);
3661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
3662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_EQ(array->length(), length);
3663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        arguments->set_elements(*array);
3664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (int i = 0; i < length; ++i) {
3665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> value = MaterializeAt(frame_index, value_index);
3666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          array->set(i, *value);
3667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot->value_ = arguments;
3670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return arguments;
3671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kCapturedObject: {
3673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int length = slot->GetChildrenCount();
3674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The map must be a tagged object.
3676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK(frame->values_[*value_index].kind() == TranslatedValue::kTagged);
3677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> result;
3679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (slot->value_.ToHandle(&result)) {
3680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // This has been previously materialized, return the previous value.
3681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // We still need to skip all the nested objects.
3682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (int i = 0; i < length; i++) {
3683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          MaterializeAt(frame_index, value_index);
3684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return result;
3687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> map_object = MaterializeAt(frame_index, value_index);
3690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Map> map =
3691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Map::GeneralizeAllFieldRepresentations(Handle<Map>::cast(map_object));
3692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      switch (map->instance_type()) {
3693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case MUTABLE_HEAP_NUMBER_TYPE:
3694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case HEAP_NUMBER_TYPE: {
3695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Reuse the HeapNumber value directly as it is already properly
3696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // tagged and skip materializing the HeapNumber explicitly.
3697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> object = MaterializeAt(frame_index, value_index);
3698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // On 32-bit architectures, there is an extra slot there because
3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // the escape analysis calculates the number of slots as
3701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // object-size/pointer-size. To account for this, we read out
3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // any extra slots.
3703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          for (int i = 0; i < length - 2; i++) {
3704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            MaterializeAt(frame_index, value_index);
3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
3706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return object;
3707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
370813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case JS_OBJECT_TYPE:
370913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case JS_ERROR_TYPE:
371013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case JS_ARGUMENTS_TYPE: {
3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Handle<JSObject> object =
3712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED);
3713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> properties = MaterializeAt(frame_index, value_index);
3715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> elements = MaterializeAt(frame_index, value_index);
3716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_properties(FixedArray::cast(*properties));
3717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_elements(FixedArrayBase::cast(*elements));
3718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          for (int i = 0; i < length - 3; ++i) {
3719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<Object> value = MaterializeAt(frame_index, value_index);
3720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i);
3721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            object->FastPropertyAtPut(index, *value);
3722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return object;
3724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case JS_ARRAY_TYPE: {
3726f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<JSArray> object = Handle<JSArray>::cast(
3727f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
3728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> properties = MaterializeAt(frame_index, value_index);
3730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> elements = MaterializeAt(frame_index, value_index);
3731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> length = MaterializeAt(frame_index, value_index);
3732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_properties(FixedArray::cast(*properties));
3733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_elements(FixedArrayBase::cast(*elements));
3734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          object->set_length(*length);
3735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return object;
3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
373713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case JS_FUNCTION_TYPE: {
3738f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<SharedFunctionInfo> temporary_shared =
3739f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              isolate_->factory()->NewSharedFunctionInfo(
3740f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  isolate_->factory()->empty_string(), MaybeHandle<Code>(),
3741f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  false);
374213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Handle<JSFunction> object =
374313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              isolate_->factory()->NewFunctionFromSharedFunctionInfo(
3744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  map, temporary_shared, isolate_->factory()->undefined_value(),
3745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  NOT_TENURED);
374613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          slot->value_ = object;
374713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Handle<Object> properties = MaterializeAt(frame_index, value_index);
374813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Handle<Object> elements = MaterializeAt(frame_index, value_index);
374913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Handle<Object> prototype = MaterializeAt(frame_index, value_index);
375013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Handle<Object> shared = MaterializeAt(frame_index, value_index);
375113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Handle<Object> context = MaterializeAt(frame_index, value_index);
375213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Handle<Object> literals = MaterializeAt(frame_index, value_index);
375313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Handle<Object> entry = MaterializeAt(frame_index, value_index);
375413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Handle<Object> next_link = MaterializeAt(frame_index, value_index);
375513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          object->ReplaceCode(*isolate_->builtins()->CompileLazy());
375613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          object->set_map(*map);
375713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          object->set_properties(FixedArray::cast(*properties));
375813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          object->set_elements(FixedArrayBase::cast(*elements));
375913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          object->set_prototype_or_initial_map(*prototype);
376013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          object->set_shared(SharedFunctionInfo::cast(*shared));
376113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          object->set_context(Context::cast(*context));
376213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          object->set_literals(LiteralsArray::cast(*literals));
376313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          CHECK(entry->IsNumber());  // Entry to compile lazy stub.
376413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          CHECK(next_link->IsUndefined(isolate_));
376513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          return object;
376613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        }
3767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        case CONS_STRING_TYPE: {
3768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<ConsString> object = Handle<ConsString>::cast(
3769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              isolate_->factory()
3770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  ->NewConsString(isolate_->factory()->undefined_string(),
3771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  isolate_->factory()->undefined_string())
3772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  .ToHandleChecked());
3773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          slot->value_ = object;
3774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<Object> hash = MaterializeAt(frame_index, value_index);
3775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<Object> length = MaterializeAt(frame_index, value_index);
3776f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<Object> first = MaterializeAt(frame_index, value_index);
3777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<Object> second = MaterializeAt(frame_index, value_index);
3778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          object->set_map(*map);
3779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          object->set_length(Smi::cast(*length)->value());
3780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          object->set_first(String::cast(*first));
3781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          object->set_second(String::cast(*second));
3782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          CHECK(hash->IsNumber());  // The {Name::kEmptyHashField} value.
3783f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          return object;
3784f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
3785f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        case CONTEXT_EXTENSION_TYPE: {
3786f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<ContextExtension> object =
3787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              isolate_->factory()->NewContextExtension(
3788f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  isolate_->factory()->NewScopeInfo(1),
3789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  isolate_->factory()->undefined_value());
3790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          slot->value_ = object;
3791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<Object> scope_info = MaterializeAt(frame_index, value_index);
3792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          Handle<Object> extension = MaterializeAt(frame_index, value_index);
3793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          object->set_scope_info(ScopeInfo::cast(*scope_info));
3794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          object->set_extension(*extension);
3795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          return object;
3796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
3797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case FIXED_ARRAY_TYPE: {
3798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> lengthObject = MaterializeAt(frame_index, value_index);
3799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int32_t length = 0;
3800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CHECK(lengthObject->ToInt32(&length));
3801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<FixedArray> object =
3802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewFixedArray(length);
3803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // We need to set the map, because the fixed array we are
3804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // materializing could be a context or an arguments object,
3805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // in which case we must retain that information.
3806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          object->set_map(*map);
3807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          for (int i = 0; i < length; ++i) {
3809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<Object> value = MaterializeAt(frame_index, value_index);
3810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            object->set(i, *value);
3811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return object;
3813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case FIXED_DOUBLE_ARRAY_TYPE: {
3815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map());
3816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object> lengthObject = MaterializeAt(frame_index, value_index);
3817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int32_t length = 0;
3818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CHECK(lengthObject->ToInt32(&length));
3819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<FixedArrayBase> object =
3820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate_->factory()->NewFixedDoubleArray(length);
3821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          slot->value_ = object;
3822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (length > 0) {
3823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<FixedDoubleArray> double_array =
3824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                Handle<FixedDoubleArray>::cast(object);
3825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            for (int i = 0; i < length; ++i) {
3826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              Handle<Object> value = MaterializeAt(frame_index, value_index);
3827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              CHECK(value->IsNumber());
3828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              double_array->set(i, value->Number());
3829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
3830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return object;
3832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        default:
3834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintF(stderr, "[couldn't handle instance type %d]\n",
3835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 map->instance_type());
3836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          FATAL("unreachable");
3837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return Handle<Object>::null();
3838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
3841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kDuplicatedObject: {
3844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int object_index = slot->object_index();
3845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedState::ObjectPosition pos = object_positions_[object_index];
3846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Make sure the duplicate is refering to a previous object.
3848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      CHECK(pos.frame_index_ < frame_index ||
3849109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            (pos.frame_index_ == frame_index &&
3850109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch             pos.value_index_ < *value_index - 1));
3851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> object =
3853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          frames_[pos.frame_index_].values_[pos.value_index_].GetValue();
3854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The object should have a (non-sentinel) value.
3856109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      CHECK(!object.is_null() &&
3857109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            !object.is_identical_to(isolate_->factory()->arguments_marker()));
3858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot->value_ = object;
3860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return object;
3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TranslatedValue::kInvalid:
3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
3866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("We should never get here - unexpected deopt slot kind.");
3869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Object>::null();
3870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> TranslatedState::MaterializeObjectAt(int object_index) {
3874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslatedState::ObjectPosition pos = object_positions_[object_index];
3875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return MaterializeAt(pos.frame_index_, &(pos.value_index_));
3876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result,
3880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          int frame_index) {
3881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (frame_index == 0) {
3882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Top level frame -> we need to go to the parent frame on the stack.
3883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!has_adapted_arguments_) return false;
3884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This is top level frame, so we need to go to the stack to get
3886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // this function's argument. (Note that this relies on not inlining
3887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // recursive functions!)
3888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSFunction> function =
3889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSFunction>::cast(frames_[frame_index].front().GetValue());
3890109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    *result = Accessors::FunctionGetArguments(function);
3891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame* previous_frame = &(frames_[frame_index]);
3894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (previous_frame->kind() != TranslatedFrame::kArgumentsAdaptor) {
3895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
3896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We get the adapted arguments from the parent translation.
3898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int length = previous_frame->height();
3899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSFunction> function =
3900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSFunction>::cast(previous_frame->front().GetValue());
3901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSObject> arguments =
3902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_->factory()->NewArgumentsObject(function, length);
3903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
3904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    arguments->set_elements(*array);
3905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedFrame::iterator arg_iterator = previous_frame->begin();
3906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    arg_iterator++;  // Skip function.
3907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < length; ++i) {
3908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Object> value = arg_iterator->GetValue();
3909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array->set(i, *value);
3910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arg_iterator++;
3911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(arg_iterator == previous_frame->end());
3913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *result = arguments;
3914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex(
3920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int jsframe_index, int* args_count) {
3921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < frames_.size(); i++) {
3922109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (frames_[i].kind() == TranslatedFrame::kFunction ||
3923109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        frames_[i].kind() == TranslatedFrame::kInterpretedFunction) {
3924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (jsframe_index > 0) {
3925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        jsframe_index--;
3926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // We have the JS function frame, now check if it has arguments adaptor.
3928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (i > 0 &&
3929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            frames_[i - 1].kind() == TranslatedFrame::kArgumentsAdaptor) {
3930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          *args_count = frames_[i - 1].height();
3931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return &(frames_[i - 1]);
3932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        *args_count =
3934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            frames_[i].shared_info()->internal_formal_parameter_count() + 1;
3935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return &(frames_[i]);
3936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
3940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::StoreMaterializedValuesAndDeopt() {
3944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaterializedObjectStore* materialized_store =
3945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_->materialized_object_store();
3946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> previously_materialized_objects =
3947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      materialized_store->Get(stack_frame_pointer_);
3948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> marker = isolate_->factory()->arguments_marker();
3950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length = static_cast<int>(object_positions_.size());
3952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool new_store = false;
3953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (previously_materialized_objects.is_null()) {
3954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    previously_materialized_objects =
3955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_->factory()->NewFixedArray(length);
3956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < length; i++) {
3957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      previously_materialized_objects->set(i, *marker);
3958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_store = true;
3960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3962109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK_EQ(length, previously_materialized_objects->length());
3963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool value_changed = false;
3965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < length; i++) {
3966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedState::ObjectPosition pos = object_positions_[i];
3967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslatedValue* value_info =
3968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &(frames_[pos.frame_index_].values_[pos.value_index_]);
3969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3970109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK(value_info->IsMaterializedObject());
3971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> value(value_info->GetRawValue(), isolate_);
3973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!value.is_identical_to(marker)) {
3975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (previously_materialized_objects->get(i) == *marker) {
3976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        previously_materialized_objects->set(i, *value);
3977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value_changed = true;
3978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CHECK(previously_materialized_objects->get(i) == *value);
3980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_store && value_changed) {
3984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    materialized_store->Set(stack_frame_pointer_,
3985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            previously_materialized_objects);
3986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CHECK(frames_[0].kind() == TranslatedFrame::kFunction ||
39873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          frames_[0].kind() == TranslatedFrame::kInterpretedFunction ||
39883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          frames_[0].kind() == TranslatedFrame::kTailCallerFunction);
3989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object* const function = frames_[0].front().GetRawValue();
3990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Deoptimizer::DeoptimizeFunction(JSFunction::cast(function));
3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
39928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
39938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
39948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TranslatedState::UpdateFromPreviouslyMaterializedObjects() {
3996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaterializedObjectStore* materialized_store =
3997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_->materialized_object_store();
3998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<FixedArray> previously_materialized_objects =
3999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      materialized_store->Get(stack_frame_pointer_);
40003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we have no previously materialized objects, there is nothing to do.
4002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (previously_materialized_objects.is_null()) return;
40033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> marker = isolate_->factory()->arguments_marker();
40053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length = static_cast<int>(object_positions_.size());
4007109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK_EQ(length, previously_materialized_objects->length());
40083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < length; i++) {
4010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // For a previously materialized objects, inject their value into the
4011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // translated values.
4012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (previously_materialized_objects->get(i) != *marker) {
4013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedState::ObjectPosition pos = object_positions_[i];
4014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslatedValue* value_info =
4015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          &(frames_[pos.frame_index_].values_[pos.value_index_]);
4016109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      CHECK(value_info->IsMaterializedObject());
40173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value_info->value_ =
4019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<Object>(previously_materialized_objects->get(i), isolate_);
4020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
40223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
40233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
4025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
4026