LCOV - code coverage report
Current view: top level - src - deoptimizer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1386 1667 83.1 %
Date: 2017-04-26 Functions: 108 154 70.1 %

          Line data    Source code
       1             : // Copyright 2013 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/deoptimizer.h"
       6             : 
       7             : #include <memory>
       8             : 
       9             : #include "src/accessors.h"
      10             : #include "src/assembler-inl.h"
      11             : #include "src/ast/prettyprinter.h"
      12             : #include "src/codegen.h"
      13             : #include "src/disasm.h"
      14             : #include "src/frames-inl.h"
      15             : #include "src/full-codegen/full-codegen.h"
      16             : #include "src/global-handles.h"
      17             : #include "src/interpreter/interpreter.h"
      18             : #include "src/macro-assembler.h"
      19             : #include "src/tracing/trace-event.h"
      20             : #include "src/v8.h"
      21             : 
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : 
      26      182346 : static MemoryChunk* AllocateCodeChunk(MemoryAllocator* allocator) {
      27             :   return allocator->AllocateChunk(Deoptimizer::GetMaxDeoptTableSize(),
      28      182346 :                                   MemoryAllocator::GetCommitPageSize(),
      29      182346 :                                   EXECUTABLE, NULL);
      30             : }
      31             : 
      32             : 
      33       60782 : DeoptimizerData::DeoptimizerData(MemoryAllocator* allocator)
      34             :     : allocator_(allocator),
      35       60782 :       current_(NULL) {
      36      243128 :   for (int i = 0; i <= Deoptimizer::kLastBailoutType; ++i) {
      37      182346 :     deopt_entry_code_entries_[i] = -1;
      38      182346 :     deopt_entry_code_[i] = AllocateCodeChunk(allocator);
      39             :   }
      40       60782 : }
      41             : 
      42             : 
      43       59285 : DeoptimizerData::~DeoptimizerData() {
      44      237140 :   for (int i = 0; i <= Deoptimizer::kLastBailoutType; ++i) {
      45      177855 :     allocator_->Free<MemoryAllocator::kFull>(deopt_entry_code_[i]);
      46      177855 :     deopt_entry_code_[i] = NULL;
      47             :   }
      48       59285 : }
      49             : 
      50             : 
      51      151227 : Code* Deoptimizer::FindDeoptimizingCode(Address addr) {
      52      302454 :   if (function_->IsHeapObject()) {
      53             :     // Search all deoptimizing code in the native context of the function.
      54             :     Isolate* isolate = function_->GetIsolate();
      55             :     Context* native_context = function_->context()->native_context();
      56      124580 :     Object* element = native_context->DeoptimizedCodeListHead();
      57      310858 :     while (!element->IsUndefined(isolate)) {
      58             :       Code* code = Code::cast(element);
      59      160842 :       CHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
      60      160842 :       if (code->contains(addr)) return code;
      61             :       element = code->next_code_link();
      62             :     }
      63             :   }
      64             :   return NULL;
      65             : }
      66             : 
      67             : 
      68             : // We rely on this function not causing a GC.  It is called from generated code
      69             : // without having a real stack frame in place.
      70      151227 : Deoptimizer* Deoptimizer::New(JSFunction* function,
      71             :                               BailoutType type,
      72             :                               unsigned bailout_id,
      73             :                               Address from,
      74             :                               int fp_to_sp_delta,
      75      151227 :                               Isolate* isolate) {
      76             :   Deoptimizer* deoptimizer = new Deoptimizer(isolate, function, type,
      77      151227 :                                              bailout_id, from, fp_to_sp_delta);
      78      151227 :   CHECK(isolate->deoptimizer_data()->current_ == NULL);
      79      151227 :   isolate->deoptimizer_data()->current_ = deoptimizer;
      80      151227 :   return deoptimizer;
      81             : }
      82             : 
      83             : 
      84             : // No larger than 2K on all platforms
      85             : static const int kDeoptTableMaxEpilogueCodeSize = 2 * KB;
      86             : 
      87             : 
      88      267521 : size_t Deoptimizer::GetMaxDeoptTableSize() {
      89             :   int entries_size =
      90      267521 :       Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_;
      91      267521 :   int commit_page_size = static_cast<int>(MemoryAllocator::GetCommitPageSize());
      92      267521 :   int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) /
      93      267521 :                     commit_page_size) + 1;
      94      267521 :   return static_cast<size_t>(commit_page_size * page_count);
      95             : }
      96             : 
      97             : 
      98      302454 : Deoptimizer* Deoptimizer::Grab(Isolate* isolate) {
      99      151227 :   Deoptimizer* result = isolate->deoptimizer_data()->current_;
     100      151227 :   CHECK_NOT_NULL(result);
     101      151227 :   result->DeleteFrameDescriptions();
     102      151227 :   isolate->deoptimizer_data()->current_ = NULL;
     103      151227 :   return result;
     104             : }
     105             : 
     106       48994 : DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
     107             :     JavaScriptFrame* frame,
     108             :     int jsframe_index,
     109             :     Isolate* isolate) {
     110      146982 :   CHECK(frame->is_optimized());
     111             : 
     112       48994 :   TranslatedState translated_values(frame);
     113       48994 :   translated_values.Prepare(false, frame->fp());
     114             : 
     115             :   TranslatedState::iterator frame_it = translated_values.end();
     116             :   int counter = jsframe_index;
     117      135001 :   for (auto it = translated_values.begin(); it != translated_values.end();
     118             :        it++) {
     119       86007 :     if (it->kind() == TranslatedFrame::kFunction ||
     120             :         it->kind() == TranslatedFrame::kInterpretedFunction) {
     121       67967 :       if (counter == 0) {
     122             :         frame_it = it;
     123             :         break;
     124             :       }
     125       18973 :       counter--;
     126             :     }
     127             :   }
     128       48994 :   CHECK(frame_it != translated_values.end());
     129             : 
     130             :   DeoptimizedFrameInfo* info =
     131       97988 :       new DeoptimizedFrameInfo(&translated_values, frame_it, isolate);
     132             : 
     133       48994 :   return info;
     134             : }
     135             : 
     136           0 : void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
     137             :                                                 int count,
     138             :                                                 BailoutType type) {
     139             :   TableEntryGenerator generator(masm, type, count);
     140       85175 :   generator.Generate();
     141           0 : }
     142             : 
     143       98729 : void Deoptimizer::VisitAllOptimizedFunctionsForContext(
     144             :     Context* context, OptimizedFunctionVisitor* visitor) {
     145             :   DisallowHeapAllocation no_allocation;
     146             : 
     147       98729 :   CHECK(context->IsNativeContext());
     148             : 
     149             :   // Visit the list of optimized functions, removing elements that
     150             :   // no longer refer to optimized code.
     151             :   JSFunction* prev = NULL;
     152       98729 :   Object* element = context->OptimizedFunctionsListHead();
     153             :   Isolate* isolate = context->GetIsolate();
     154     5758193 :   while (!element->IsUndefined(isolate)) {
     155             :     JSFunction* function = JSFunction::cast(element);
     156             :     Object* next = function->next_function_link();
     157    11121470 :     if (function->code()->kind() != Code::OPTIMIZED_FUNCTION ||
     158     5560735 :         (visitor->VisitFunction(function),
     159             :          function->code()->kind() != Code::OPTIMIZED_FUNCTION)) {
     160             :       // The function no longer refers to optimized code, or the visitor
     161             :       // changed the code to which it refers to no longer be optimized code.
     162             :       // Remove the function from this list.
     163      492024 :       if (prev != NULL) {
     164       28977 :         prev->set_next_function_link(next, UPDATE_WEAK_WRITE_BARRIER);
     165             :       } else {
     166      463047 :         context->SetOptimizedFunctionsListHead(next);
     167             :       }
     168             :       // The visitor should not alter the link directly.
     169      492024 :       CHECK_EQ(function->next_function_link(), next);
     170             :       // Set the next function link to undefined to indicate it is no longer
     171             :       // in the optimized functions list.
     172      492024 :       function->set_next_function_link(context->GetHeap()->undefined_value(),
     173      492024 :                                        SKIP_WRITE_BARRIER);
     174             :     } else {
     175             :       // The visitor should not alter the link directly.
     176     5068711 :       CHECK_EQ(function->next_function_link(), next);
     177             :       // preserve this element.
     178             :       prev = function;
     179             :     }
     180             :     element = next;
     181             :   }
     182       98729 : }
     183             : 
     184       25296 : void Deoptimizer::UnlinkOptimizedCode(Code* code, Context* native_context) {
     185           0 :   class CodeUnlinker : public OptimizedFunctionVisitor {
     186             :    public:
     187       25296 :     explicit CodeUnlinker(Code* code) : code_(code) {}
     188             : 
     189     4527451 :     virtual void VisitFunction(JSFunction* function) {
     190     4527451 :       if (function->code() == code_) {
     191       31857 :         if (FLAG_trace_deopt) {
     192           0 :           PrintF("[removing optimized code for: ");
     193           0 :           function->ShortPrint();
     194           0 :           PrintF("]\n");
     195             :         }
     196       31857 :         function->set_code(function->shared()->code());
     197             :       }
     198     4527451 :     }
     199             : 
     200             :    private:
     201             :     Code* code_;
     202             :   };
     203             :   CodeUnlinker unlinker(code);
     204       25296 :   VisitAllOptimizedFunctionsForContext(native_context, &unlinker);
     205       25296 : }
     206             : 
     207             : 
     208        2710 : void Deoptimizer::VisitAllOptimizedFunctions(
     209             :     Isolate* isolate,
     210             :     OptimizedFunctionVisitor* visitor) {
     211             :   DisallowHeapAllocation no_allocation;
     212             : 
     213             :   // Run through the list of all native contexts.
     214        2710 :   Object* context = isolate->heap()->native_contexts_list();
     215       10146 :   while (!context->IsUndefined(isolate)) {
     216        4726 :     VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor);
     217             :     context = Context::cast(context)->next_context_link();
     218             :   }
     219        2710 : }
     220             : 
     221             : 
     222             : // Unlink functions referring to code marked for deoptimization, then move
     223             : // marked code from the optimized code list to the deoptimized code list,
     224             : // and patch code for lazy deopt.
     225       68707 : void Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) {
     226             :   DisallowHeapAllocation no_allocation;
     227             : 
     228             :   // A "closure" that unlinks optimized code that is going to be
     229             :   // deoptimized from the functions that refer to it.
     230           0 :   class SelectedCodeUnlinker: public OptimizedFunctionVisitor {
     231             :    public:
     232      990178 :     virtual void VisitFunction(JSFunction* function) {
     233      990178 :       Code* code = function->code();
     234     1980356 :       if (!code->marked_for_deoptimization()) return;
     235             : 
     236             :       // Unlink this function and evict from optimized code map.
     237             :       SharedFunctionInfo* shared = function->shared();
     238      460167 :       if (!code->deopt_already_counted()) {
     239             :         shared->increment_deopt_count();
     240             :         code->set_deopt_already_counted(true);
     241             :       }
     242      460167 :       function->set_code(shared->code());
     243             : 
     244      460167 :       if (FLAG_trace_deopt) {
     245           0 :         CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
     246           0 :         PrintF(scope.file(), "[deoptimizer unlinked: ");
     247           0 :         function->PrintName(scope.file());
     248             :         PrintF(scope.file(),
     249           0 :                " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
     250             :       }
     251             :     }
     252             :   };
     253             : 
     254             :   // Unlink all functions that refer to marked code.
     255       68707 :   SelectedCodeUnlinker unlinker;
     256       68707 :   VisitAllOptimizedFunctionsForContext(context, &unlinker);
     257             : 
     258       68707 :   Isolate* isolate = context->GetHeap()->isolate();
     259             : #ifdef DEBUG
     260             :   Code* topmost_optimized_code = NULL;
     261             :   bool safe_to_deopt_topmost_optimized_code = false;
     262             :   // Make sure all activations of optimized code can deopt at their current PC.
     263             :   // The topmost optimized code has special handling because it cannot be
     264             :   // deoptimized due to weak object dependency.
     265             :   for (StackFrameIterator it(isolate, isolate->thread_local_top());
     266             :        !it.done(); it.Advance()) {
     267             :     StackFrame::Type type = it.frame()->type();
     268             :     if (type == StackFrame::OPTIMIZED) {
     269             :       Code* code = it.frame()->LookupCode();
     270             :       JSFunction* function =
     271             :           static_cast<OptimizedFrame*>(it.frame())->function();
     272             :       if (FLAG_trace_deopt) {
     273             :         CodeTracer::Scope scope(isolate->GetCodeTracer());
     274             :         PrintF(scope.file(), "[deoptimizer found activation of function: ");
     275             :         function->PrintName(scope.file());
     276             :         PrintF(scope.file(),
     277             :                " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
     278             :       }
     279             :       SafepointEntry safepoint = code->GetSafepointEntry(it.frame()->pc());
     280             :       int deopt_index = safepoint.deoptimization_index();
     281             :       // Turbofan deopt is checked when we are patching addresses on stack.
     282             :       bool turbofanned =
     283             :           code->is_turbofanned() && function->shared()->asm_function();
     284             :       bool safe_to_deopt =
     285             :           deopt_index != Safepoint::kNoDeoptimizationIndex || turbofanned;
     286             :       bool builtin = code->kind() == Code::BUILTIN;
     287             :       CHECK(topmost_optimized_code == NULL || safe_to_deopt || turbofanned ||
     288             :             builtin);
     289             :       if (topmost_optimized_code == NULL) {
     290             :         topmost_optimized_code = code;
     291             :         safe_to_deopt_topmost_optimized_code = safe_to_deopt;
     292             :       }
     293             :     }
     294             :   }
     295             : #endif
     296             : 
     297             :   // Move marked code from the optimized code list to the deoptimized
     298             :   // code list, collecting them into a ZoneList.
     299      137414 :   Zone zone(isolate->allocator(), ZONE_NAME);
     300       68707 :   ZoneList<Code*> codes(10, &zone);
     301             : 
     302             :   // Walk over all optimized code objects in this native context.
     303             :   Code* prev = NULL;
     304       68707 :   Object* element = context->OptimizedCodeListHead();
     305      860181 :   while (!element->IsUndefined(isolate)) {
     306             :     Code* code = Code::cast(element);
     307      722767 :     CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
     308             :     Object* next = code->next_code_link();
     309             : 
     310      722767 :     if (code->marked_for_deoptimization()) {
     311             :       // Put the code into the list for later patching.
     312             :       codes.Add(code, &zone);
     313             : 
     314      422165 :       if (prev != NULL) {
     315             :         // Skip this code in the optimized code list.
     316        5731 :         prev->set_next_code_link(next);
     317             :       } else {
     318             :         // There was no previous node, the next node is the new head.
     319      416434 :         context->SetOptimizedCodeListHead(next);
     320             :       }
     321             : 
     322             :       // Move the code to the _deoptimized_ code list.
     323      422165 :       code->set_next_code_link(context->DeoptimizedCodeListHead());
     324      422165 :       context->SetDeoptimizedCodeListHead(code);
     325             :     } else {
     326             :       // Not marked; preserve this element.
     327             :       prev = code;
     328             :     }
     329             :     element = next;
     330             :   }
     331             : 
     332             :   // We need a handle scope only because of the macro assembler,
     333             :   // which is used in code patching in EnsureCodeForDeoptimizationEntry.
     334             :   HandleScope scope(isolate);
     335             : 
     336             :   // Now patch all the codes for deoptimization.
     337      490872 :   for (int i = 0; i < codes.length(); i++) {
     338             : #ifdef DEBUG
     339             :     if (codes[i] == topmost_optimized_code) {
     340             :       DCHECK(safe_to_deopt_topmost_optimized_code);
     341             :     }
     342             : #endif
     343             :     // It is finally time to die, code object.
     344             : 
     345             :     // Remove the code from optimized code map.
     346             :     DeoptimizationInputData* deopt_data =
     347      844330 :         DeoptimizationInputData::cast(codes[i]->deoptimization_data());
     348             :     SharedFunctionInfo* shared =
     349             :         SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo());
     350      844330 :     shared->EvictFromOptimizedCodeMap(codes[i], "deoptimized code");
     351             : 
     352             :     // Do platform-specific patching to force any activations to lazy deopt.
     353      844330 :     PatchCodeForDeoptimization(isolate, codes[i]);
     354             : 
     355             :     // We might be in the middle of incremental marking with compaction.
     356             :     // Tell collector to treat this code object in a special way and
     357             :     // ignore all slots that might have been recorded on it.
     358      844330 :     isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]);
     359             :   }
     360       68707 : }
     361             : 
     362             : 
     363        9338 : void Deoptimizer::DeoptimizeAll(Isolate* isolate) {
     364             :   RuntimeCallTimerScope runtimeTimer(isolate,
     365        9338 :                                      &RuntimeCallStats::DeoptimizeCode);
     366             :   TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
     367       28014 :   TRACE_EVENT0("v8", "V8.DeoptimizeCode");
     368        9338 :   if (FLAG_trace_deopt) {
     369           0 :     CodeTracer::Scope scope(isolate->GetCodeTracer());
     370           0 :     PrintF(scope.file(), "[deoptimize all code in all contexts]\n");
     371             :   }
     372             :   DisallowHeapAllocation no_allocation;
     373             :   // For all contexts, mark all code, then deoptimize.
     374        9338 :   Object* context = isolate->heap()->native_contexts_list();
     375       59351 :   while (!context->IsUndefined(isolate)) {
     376             :     Context* native_context = Context::cast(context);
     377       40675 :     MarkAllCodeForContext(native_context);
     378       40675 :     DeoptimizeMarkedCodeForContext(native_context);
     379             :     context = native_context->next_context_link();
     380             :   }
     381        9338 : }
     382             : 
     383             : 
     384        7211 : void Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) {
     385             :   RuntimeCallTimerScope runtimeTimer(isolate,
     386        7211 :                                      &RuntimeCallStats::DeoptimizeCode);
     387             :   TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
     388       21633 :   TRACE_EVENT0("v8", "V8.DeoptimizeCode");
     389        7211 :   if (FLAG_trace_deopt) {
     390           0 :     CodeTracer::Scope scope(isolate->GetCodeTracer());
     391           0 :     PrintF(scope.file(), "[deoptimize marked code in all contexts]\n");
     392             :   }
     393             :   DisallowHeapAllocation no_allocation;
     394             :   // For all contexts, deoptimize code already marked.
     395        7211 :   Object* context = isolate->heap()->native_contexts_list();
     396       35796 :   while (!context->IsUndefined(isolate)) {
     397             :     Context* native_context = Context::cast(context);
     398       21374 :     DeoptimizeMarkedCodeForContext(native_context);
     399             :     context = native_context->next_context_link();
     400             :   }
     401        7211 : }
     402             : 
     403             : 
     404       40675 : void Deoptimizer::MarkAllCodeForContext(Context* context) {
     405       40675 :   Object* element = context->OptimizedCodeListHead();
     406             :   Isolate* isolate = context->GetIsolate();
     407      484336 :   while (!element->IsUndefined(isolate)) {
     408             :     Code* code = Code::cast(element);
     409      402986 :     CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
     410             :     code->set_marked_for_deoptimization(true);
     411             :     element = code->next_code_link();
     412             :   }
     413       40675 : }
     414             : 
     415       37980 : void Deoptimizer::DeoptimizeFunction(JSFunction* function, Code* code) {
     416             :   Isolate* isolate = function->GetIsolate();
     417             :   RuntimeCallTimerScope runtimeTimer(isolate,
     418       37980 :                                      &RuntimeCallStats::DeoptimizeCode);
     419             :   TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
     420      113940 :   TRACE_EVENT0("v8", "V8.DeoptimizeCode");
     421       75849 :   if (code == nullptr) code = function->code();
     422       37980 :   if (code->kind() == Code::OPTIMIZED_FUNCTION) {
     423             :     // Mark the code for deoptimization and unlink any functions that also
     424             :     // refer to that code. The code cannot be shared across native contexts,
     425             :     // so we only need to search one.
     426             :     code->set_marked_for_deoptimization(true);
     427        6658 :     DeoptimizeMarkedCodeForContext(function->context()->native_context());
     428             :   }
     429       37980 : }
     430             : 
     431             : 
     432      151227 : void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
     433      151227 :   deoptimizer->DoComputeOutputFrames();
     434      151227 : }
     435             : 
     436           0 : bool Deoptimizer::TraceEnabledFor(StackFrame::Type frame_type) {
     437             :   return (frame_type == StackFrame::STUB) ? FLAG_trace_stub_failures
     438      151227 :                                           : FLAG_trace_deopt;
     439             : }
     440             : 
     441             : 
     442           0 : const char* Deoptimizer::MessageFor(BailoutType type) {
     443           0 :   switch (type) {
     444             :     case EAGER: return "eager";
     445           0 :     case SOFT: return "soft";
     446           0 :     case LAZY: return "lazy";
     447             :   }
     448           0 :   FATAL("Unsupported deopt type");
     449             :   return NULL;
     450             : }
     451             : 
     452             : namespace {
     453             : 
     454      124580 : CodeEventListener::DeoptKind DeoptKindOfBailoutType(
     455             :     Deoptimizer::BailoutType bailout_type) {
     456      124580 :   switch (bailout_type) {
     457             :     case Deoptimizer::EAGER:
     458             :       return CodeEventListener::kEager;
     459             :     case Deoptimizer::SOFT:
     460        2442 :       return CodeEventListener::kSoft;
     461             :     case Deoptimizer::LAZY:
     462       99144 :       return CodeEventListener::kLazy;
     463             :   }
     464           0 :   UNREACHABLE();
     465             :   return CodeEventListener::kEager;
     466             : }
     467             : 
     468             : }  // namespace
     469             : 
     470      304082 : Deoptimizer::Deoptimizer(Isolate* isolate, JSFunction* function,
     471             :                          BailoutType type, unsigned bailout_id, Address from,
     472             :                          int fp_to_sp_delta)
     473             :     : isolate_(isolate),
     474             :       function_(function),
     475             :       bailout_id_(bailout_id),
     476             :       bailout_type_(type),
     477             :       from_(from),
     478             :       fp_to_sp_delta_(fp_to_sp_delta),
     479             :       deoptimizing_throw_(false),
     480             :       catch_handler_data_(-1),
     481             :       catch_handler_pc_offset_(-1),
     482             :       input_(nullptr),
     483             :       output_count_(0),
     484             :       jsframe_count_(0),
     485             :       output_(nullptr),
     486             :       caller_frame_top_(0),
     487             :       caller_fp_(0),
     488             :       caller_pc_(0),
     489             :       caller_constant_pool_(0),
     490             :       input_frame_context_(0),
     491             :       stack_fp_(0),
     492      302454 :       trace_scope_(nullptr) {
     493      151227 :   if (isolate->deoptimizer_lazy_throw()) {
     494             :     isolate->set_deoptimizer_lazy_throw(false);
     495         505 :     deoptimizing_throw_ = true;
     496             :   }
     497             : 
     498             :   // For COMPILED_STUBs called from builtins, the function pointer is a SMI
     499             :   // indicating an internal frame.
     500      151227 :   if (function->IsSmi()) {
     501             :     function = nullptr;
     502             :   }
     503             :   DCHECK(from != nullptr);
     504      151227 :   compiled_code_ = FindOptimizedCode(function);
     505             : #if DEBUG
     506             :   DCHECK(compiled_code_ != NULL);
     507             :   if (type == EAGER || type == SOFT || type == LAZY) {
     508             :     DCHECK(compiled_code_->kind() != Code::FUNCTION);
     509             :   }
     510             : #endif
     511             : 
     512             :   StackFrame::Type frame_type = function == NULL
     513             :       ? StackFrame::STUB
     514      151227 :       : StackFrame::JAVA_SCRIPT;
     515             :   trace_scope_ = TraceEnabledFor(frame_type)
     516             :                      ? new CodeTracer::Scope(isolate->GetCodeTracer())
     517      302454 :                      : NULL;
     518             : #ifdef DEBUG
     519             :   CHECK(AllowHeapAllocation::IsAllowed());
     520             :   disallow_heap_allocation_ = new DisallowHeapAllocation();
     521             : #endif  // DEBUG
     522      451408 :   if (function != nullptr && function->IsOptimized() &&
     523       48748 :       (compiled_code_->kind() != Code::OPTIMIZED_FUNCTION ||
     524             :        !compiled_code_->deopt_already_counted())) {
     525             :     // If the function is optimized, and we haven't counted that deopt yet, then
     526             :     // increment the function's deopt count so that we can avoid optimising
     527             :     // functions that deopt too often.
     528             : 
     529       24373 :     if (bailout_type_ == Deoptimizer::SOFT) {
     530             :       // Soft deopts shouldn't count against the overall deoptimization count
     531             :       // that can eventually lead to disabling optimization for a function.
     532        1628 :       isolate->counters()->soft_deopts_executed()->Increment();
     533             :     } else {
     534             :       function->shared()->increment_deopt_count();
     535             :     }
     536             :   }
     537      302454 :   if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
     538             :     compiled_code_->set_deopt_already_counted(true);
     539      249160 :     PROFILE(isolate_,
     540             :             CodeDeoptEvent(compiled_code_, DeoptKindOfBailoutType(type), from_,
     541             :                            fp_to_sp_delta_));
     542             :   }
     543      151227 :   unsigned size = ComputeInputFrameSize();
     544             :   int parameter_count =
     545             :       function == nullptr
     546             :           ? 0
     547      275807 :           : (function->shared()->internal_formal_parameter_count() + 1);
     548      151227 :   input_ = new (size) FrameDescription(size, parameter_count);
     549             :   input_->SetFrameType(frame_type);
     550      151227 : }
     551             : 
     552      151227 : Code* Deoptimizer::FindOptimizedCode(JSFunction* function) {
     553      151227 :   Code* compiled_code = FindDeoptimizingCode(from_);
     554             :   return (compiled_code == NULL)
     555       52083 :              ? static_cast<Code*>(isolate_->FindCodeObject(from_))
     556      203310 :              : compiled_code;
     557             : }
     558             : 
     559             : 
     560           0 : void Deoptimizer::PrintFunctionName() {
     561           0 :   if (function_->IsHeapObject() && function_->IsJSFunction()) {
     562           0 :     function_->ShortPrint(trace_scope_->file());
     563             :   } else {
     564             :     PrintF(trace_scope_->file(),
     565           0 :            "%s", Code::Kind2String(compiled_code_->kind()));
     566             :   }
     567           0 : }
     568             : 
     569             : 
     570      151227 : Deoptimizer::~Deoptimizer() {
     571             :   DCHECK(input_ == NULL && output_ == NULL);
     572             :   DCHECK(disallow_heap_allocation_ == NULL);
     573      151227 :   delete trace_scope_;
     574      151227 : }
     575             : 
     576             : 
     577      151227 : void Deoptimizer::DeleteFrameDescriptions() {
     578      151227 :   delete input_;
     579      306284 :   for (int i = 0; i < output_count_; ++i) {
     580      155057 :     if (output_[i] != input_) delete output_[i];
     581             :   }
     582      151227 :   delete[] output_;
     583      151227 :   input_ = NULL;
     584      151227 :   output_ = NULL;
     585             : #ifdef DEBUG
     586             :   CHECK(!AllowHeapAllocation::IsAllowed());
     587             :   CHECK(disallow_heap_allocation_ != NULL);
     588             :   delete disallow_heap_allocation_;
     589             :   disallow_heap_allocation_ = NULL;
     590             : #endif  // DEBUG
     591      151227 : }
     592             : 
     593             : 
     594    36005751 : Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
     595             :                                             int id,
     596             :                                             BailoutType type,
     597             :                                             GetEntryMode mode) {
     598    18002817 :   CHECK_GE(id, 0);
     599    18002817 :   if (id >= kMaxNumberOfEntries) return NULL;
     600    18002820 :   if (mode == ENSURE_ENTRY_CODE) {
     601    18002820 :     EnsureCodeForDeoptimizationEntry(isolate, type, id);
     602             :   } else {
     603           0 :     CHECK_EQ(mode, CALCULATE_ENTRY_ADDRESS);
     604             :   }
     605             :   DeoptimizerData* data = isolate->deoptimizer_data();
     606    18002934 :   CHECK_LE(type, kLastBailoutType);
     607    18002934 :   MemoryChunk* base = data->deopt_entry_code_[type];
     608    18002934 :   return base->area_start() + (id * table_entry_size_);
     609             : }
     610             : 
     611             : 
     612     3000411 : int Deoptimizer::GetDeoptimizationId(Isolate* isolate,
     613             :                                      Address addr,
     614             :                                      BailoutType type) {
     615             :   DeoptimizerData* data = isolate->deoptimizer_data();
     616     3000411 :   MemoryChunk* base = data->deopt_entry_code_[type];
     617             :   Address start = base->area_start();
     618     3070425 :   if (addr < start ||
     619       70014 :       addr >= start + (kMaxNumberOfEntries * table_entry_size_)) {
     620             :     return kNotDeoptimizationEntry;
     621             :   }
     622             :   DCHECK_EQ(0,
     623             :             static_cast<int>(addr - start) % table_entry_size_);
     624       35007 :   return static_cast<int>(addr - start) / table_entry_size_;
     625             : }
     626             : 
     627             : 
     628      570503 : int Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
     629             :                                BailoutId id,
     630             :                                SharedFunctionInfo* shared) {
     631             :   // TODO(kasperl): For now, we do a simple linear search for the PC
     632             :   // offset associated with the given node id. This should probably be
     633             :   // changed to a binary search.
     634             :   int length = data->DeoptPoints();
     635    24903103 :   for (int i = 0; i < length; i++) {
     636    49806206 :     if (data->AstId(i) == id) {
     637             :       return data->PcAndState(i)->value();
     638             :     }
     639             :   }
     640           0 :   OFStream os(stderr);
     641           0 :   os << "[couldn't find pc offset for node=" << id.ToInt() << "]\n"
     642           0 :      << "[method: " << shared->DebugName()->ToCString().get() << "]\n"
     643           0 :      << "[source:\n" << SourceCodeOf(shared) << "\n]" << std::endl;
     644             : 
     645             :   shared->GetHeap()->isolate()->PushStackTraceAndDie(0xfefefefe, data, shared,
     646           0 :                                                      0xfefefeff);
     647           0 :   FATAL("unable to find pc offset during deoptimization");
     648             :   return -1;
     649             : }
     650             : 
     651             : 
     652         119 : int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) {
     653             :   int length = 0;
     654             :   // Count all entries in the deoptimizing code list of every context.
     655         119 :   Object* context = isolate->heap()->native_contexts_list();
     656         357 :   while (!context->IsUndefined(isolate)) {
     657             :     Context* native_context = Context::cast(context);
     658         119 :     Object* element = native_context->DeoptimizedCodeListHead();
     659         238 :     while (!element->IsUndefined(isolate)) {
     660             :       Code* code = Code::cast(element);
     661             :       DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
     662           0 :       length++;
     663             :       element = code->next_code_link();
     664             :     }
     665             :     context = Context::cast(context)->next_context_link();
     666             :   }
     667         119 :   return length;
     668             : }
     669             : 
     670             : namespace {
     671             : 
     672         543 : int LookupCatchHandler(TranslatedFrame* translated_frame, int* data_out) {
     673         543 :   switch (translated_frame->kind()) {
     674             :     case TranslatedFrame::kFunction: {
     675             : #ifdef DEBUG
     676             :       JSFunction* function =
     677             :           JSFunction::cast(translated_frame->begin()->GetRawValue());
     678             :       Code* non_optimized_code = function->shared()->code();
     679             :       HandlerTable* table =
     680             :           HandlerTable::cast(non_optimized_code->handler_table());
     681             :       DCHECK_EQ(0, table->NumberOfRangeEntries());
     682             : #endif
     683             :       break;
     684             :     }
     685             :     case TranslatedFrame::kInterpretedFunction: {
     686             :       int bytecode_offset = translated_frame->node_id().ToInt();
     687             :       JSFunction* function =
     688         543 :           JSFunction::cast(translated_frame->begin()->GetRawValue());
     689             :       BytecodeArray* bytecode = function->shared()->bytecode_array();
     690             :       HandlerTable* table = HandlerTable::cast(bytecode->handler_table());
     691         543 :       return table->LookupRange(bytecode_offset, data_out, nullptr);
     692             :     }
     693             :     default:
     694             :       break;
     695             :   }
     696             :   return -1;
     697             : }
     698             : 
     699             : }  // namespace
     700             : 
     701             : // We rely on this function not causing a GC.  It is called from generated code
     702             : // without having a real stack frame in place.
     703      151227 : void Deoptimizer::DoComputeOutputFrames() {
     704             :   base::ElapsedTimer timer;
     705             : 
     706             :   // Determine basic deoptimization information.  The optimized frame is
     707             :   // described by the input data.
     708             :   DeoptimizationInputData* input_data =
     709      151227 :       DeoptimizationInputData::cast(compiled_code_->deoptimization_data());
     710             : 
     711             :   {
     712             :     // Read caller's PC, caller's FP and caller's constant pool values
     713             :     // from input frame. Compute caller's frame top address.
     714             : 
     715      151227 :     Register fp_reg = JavaScriptFrame::fp_register();
     716      302454 :     stack_fp_ = input_->GetRegister(fp_reg.code());
     717             : 
     718      151227 :     caller_frame_top_ = stack_fp_ + ComputeInputFrameAboveFpFixedSize();
     719             : 
     720             :     Address fp_address = input_->GetFramePointerAddress();
     721      151227 :     caller_fp_ = Memory::intptr_at(fp_address);
     722             :     caller_pc_ =
     723      151227 :         Memory::intptr_at(fp_address + CommonFrameConstants::kCallerPCOffset);
     724             :     input_frame_context_ = Memory::intptr_at(
     725      151227 :         fp_address + CommonFrameConstants::kContextOrFrameTypeOffset);
     726             : 
     727             :     if (FLAG_enable_embedded_constant_pool) {
     728             :       caller_constant_pool_ = Memory::intptr_at(
     729             :           fp_address + CommonFrameConstants::kConstantPoolOffset);
     730             :     }
     731             :   }
     732             : 
     733      151227 :   if (trace_scope_ != NULL) {
     734             :     timer.Start();
     735             :     PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ",
     736           0 :            MessageFor(bailout_type_));
     737           0 :     PrintFunctionName();
     738             :     PrintF(trace_scope_->file(),
     739             :            " (opt #%d) @%d, FP to SP delta: %d, caller sp: 0x%08" V8PRIxPTR
     740             :            "]\n",
     741             :            input_data->OptimizationId()->value(), bailout_id_, fp_to_sp_delta_,
     742           0 :            caller_frame_top_);
     743           0 :     if (bailout_type_ == EAGER || bailout_type_ == SOFT ||
     744           0 :         (compiled_code_->is_hydrogen_stub())) {
     745           0 :       compiled_code_->PrintDeoptLocation(trace_scope_->file(), from_);
     746             :     }
     747             :   }
     748             : 
     749      151227 :   BailoutId node_id = input_data->AstId(bailout_id_);
     750             :   ByteArray* translations = input_data->TranslationByteArray();
     751             :   unsigned translation_index =
     752      151227 :       input_data->TranslationIndex(bailout_id_)->value();
     753             : 
     754             :   TranslationIterator state_iterator(translations, translation_index);
     755             :   translated_state_.Init(
     756             :       input_->GetFramePointerAddress(), &state_iterator,
     757             :       input_data->LiteralArray(), input_->GetRegisterValues(),
     758      151227 :       trace_scope_ == nullptr ? nullptr : trace_scope_->file(),
     759      151227 :       function_->IsHeapObject()
     760             :           ? function_->shared()->internal_formal_parameter_count()
     761      756135 :           : 0);
     762             : 
     763             :   // Do the input frame to output frame(s) translation.
     764      151227 :   size_t count = translated_state_.frames().size();
     765             :   // If we are supposed to go to the catch handler, find the catching frame
     766             :   // for the catch and make sure we only deoptimize upto that frame.
     767      151227 :   if (deoptimizing_throw_) {
     768             :     size_t catch_handler_frame_index = count;
     769         543 :     for (size_t i = count; i-- > 0;) {
     770             :       catch_handler_pc_offset_ = LookupCatchHandler(
     771         543 :           &(translated_state_.frames()[i]), &catch_handler_data_);
     772         543 :       if (catch_handler_pc_offset_ >= 0) {
     773             :         catch_handler_frame_index = i;
     774             :         break;
     775             :       }
     776             :     }
     777         505 :     CHECK_LT(catch_handler_frame_index, count);
     778         505 :     count = catch_handler_frame_index + 1;
     779             :   }
     780             : 
     781             :   DCHECK(output_ == NULL);
     782      151227 :   output_ = new FrameDescription*[count];
     783      306334 :   for (size_t i = 0; i < count; ++i) {
     784      155107 :     output_[i] = NULL;
     785             :   }
     786      151227 :   output_count_ = static_cast<int>(count);
     787             : 
     788             :   // Translate each output frame.
     789             :   int frame_index = 0;  // output_frame_index
     790      306334 :   for (size_t i = 0; i < count; ++i, ++frame_index) {
     791             :     // Read the ast node id, function, and frame height for this output frame.
     792      310214 :     TranslatedFrame* translated_frame = &(translated_state_.frames()[i]);
     793      155107 :     switch (translated_frame->kind()) {
     794             :       case TranslatedFrame::kFunction:
     795             :         DoComputeJSFrame(translated_frame, frame_index,
     796       18105 :                          deoptimizing_throw_ && i == count - 1);
     797       18105 :         jsframe_count_++;
     798       18105 :         break;
     799             :       case TranslatedFrame::kInterpretedFunction:
     800             :         DoComputeInterpretedFrame(translated_frame, frame_index,
     801      109251 :                                   deoptimizing_throw_ && i == count - 1);
     802      109251 :         jsframe_count_++;
     803      109251 :         break;
     804             :       case TranslatedFrame::kArgumentsAdaptor:
     805         416 :         DoComputeArgumentsAdaptorFrame(translated_frame, frame_index);
     806         416 :         break;
     807             :       case TranslatedFrame::kTailCallerFunction:
     808          50 :         DoComputeTailCallerFrame(translated_frame, frame_index);
     809             :         // Tail caller frame translations do not produce output frames.
     810          50 :         frame_index--;
     811          50 :         output_count_--;
     812          50 :         break;
     813             :       case TranslatedFrame::kConstructStub:
     814         282 :         DoComputeConstructStubFrame(translated_frame, frame_index);
     815         282 :         break;
     816             :       case TranslatedFrame::kGetter:
     817         133 :         DoComputeAccessorStubFrame(translated_frame, frame_index, false);
     818         133 :         break;
     819             :       case TranslatedFrame::kSetter:
     820         223 :         DoComputeAccessorStubFrame(translated_frame, frame_index, true);
     821         223 :         break;
     822             :       case TranslatedFrame::kCompiledStub:
     823       26647 :         DoComputeCompiledStubFrame(translated_frame, frame_index);
     824       26647 :         break;
     825             :       case TranslatedFrame::kInvalid:
     826           0 :         FATAL("invalid frame");
     827             :         break;
     828             :     }
     829             :   }
     830             : 
     831             :   // Print some helpful diagnostic information.
     832      151227 :   if (trace_scope_ != NULL) {
     833           0 :     double ms = timer.Elapsed().InMillisecondsF();
     834           0 :     int index = output_count_ - 1;  // Index of the topmost frame.
     835             :     PrintF(trace_scope_->file(), "[deoptimizing (%s): end ",
     836           0 :            MessageFor(bailout_type_));
     837           0 :     PrintFunctionName();
     838             :     PrintF(trace_scope_->file(),
     839             :            " @%d => node=%d, pc=0x%08" V8PRIxPTR ", caller sp=0x%08" V8PRIxPTR
     840             :            ", state=%s, took %0.3f ms]\n",
     841             :            bailout_id_, node_id.ToInt(), output_[index]->GetPc(),
     842             :            caller_frame_top_, BailoutStateToString(static_cast<BailoutState>(
     843           0 :                                   output_[index]->GetState()->value())),
     844           0 :            ms);
     845             :   }
     846      151227 : }
     847             : 
     848       36210 : void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame,
     849             :                                    int frame_index, bool goto_catch_handler) {
     850             :   SharedFunctionInfo* shared = translated_frame->raw_shared_info();
     851             : 
     852             :   TranslatedFrame::iterator value_iterator = translated_frame->begin();
     853       18105 :   bool is_bottommost = (0 == frame_index);
     854       18105 :   bool is_topmost = (output_count_ - 1 == frame_index);
     855       18105 :   int input_index = 0;
     856             : 
     857             :   BailoutId node_id = translated_frame->node_id();
     858             :   unsigned height =
     859       18105 :       translated_frame->height() - 1;  // Do not count the context.
     860       18105 :   unsigned height_in_bytes = height * kPointerSize;
     861       18105 :   if (goto_catch_handler) {
     862             :     // Take the stack height from the handler table.
     863           0 :     height = catch_handler_data_;
     864             :     // We also make space for the exception itself.
     865           0 :     height_in_bytes = (height + 1) * kPointerSize;
     866           0 :     CHECK(is_topmost);
     867             :   }
     868             : 
     869       18105 :   JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
     870             :   value_iterator++;
     871       18105 :   input_index++;
     872       18105 :   if (trace_scope_ != NULL) {
     873           0 :     PrintF(trace_scope_->file(), "  translating frame ");
     874           0 :     std::unique_ptr<char[]> name = shared->DebugName()->ToCString();
     875           0 :     PrintF(trace_scope_->file(), "%s", name.get());
     876             :     PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(),
     877           0 :            height_in_bytes, goto_catch_handler ? " (throw)" : "");
     878             :   }
     879             : 
     880             :   // The 'fixed' part of the frame consists of the incoming parameters and
     881             :   // the part described by JavaScriptFrameConstants.
     882             :   unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared);
     883       18105 :   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
     884             : 
     885             :   // Allocate and store the output frame description.
     886             :   int parameter_count = shared->internal_formal_parameter_count() + 1;
     887             :   FrameDescription* output_frame = new (output_frame_size)
     888       18105 :       FrameDescription(output_frame_size, parameter_count);
     889             :   output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
     890             : 
     891       18105 :   CHECK(frame_index >= 0 && frame_index < output_count_);
     892       18105 :   CHECK_NULL(output_[frame_index]);
     893       18105 :   output_[frame_index] = output_frame;
     894             : 
     895             :   // The top address of the frame is computed from the previous frame's top and
     896             :   // this frame's size.
     897             :   intptr_t top_address;
     898       18105 :   if (is_bottommost) {
     899       16729 :     top_address = caller_frame_top_ - output_frame_size;
     900             :   } else {
     901        4128 :     top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
     902             :   }
     903             :   output_frame->SetTop(top_address);
     904             : 
     905             :   // Compute the incoming parameter translation.
     906             :   unsigned output_offset = output_frame_size;
     907       54641 :   for (int i = 0; i < parameter_count; ++i) {
     908       36536 :     output_offset -= kPointerSize;
     909             :     WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
     910       36536 :                                  output_offset);
     911             :   }
     912             : 
     913       18105 :   if (trace_scope_ != nullptr) {
     914           0 :     PrintF(trace_scope_->file(), "    -------------------------\n");
     915             :   }
     916             : 
     917             :   // There are no translation commands for the caller's pc and fp, the
     918             :   // context, and the function.  Synthesize their values and set them up
     919             :   // explicitly.
     920             :   //
     921             :   // The caller's pc for the bottommost output frame is the same as in the
     922             :   // input frame.  For all subsequent output frames, it can be read from the
     923             :   // previous one.  This frame's pc can be computed from the non-optimized
     924             :   // function code and AST id of the bailout.
     925       18105 :   output_offset -= kPCOnStackSize;
     926             :   intptr_t value;
     927       18105 :   if (is_bottommost) {
     928       16729 :     value = caller_pc_;
     929             :   } else {
     930        1376 :     value = output_[frame_index - 1]->GetPc();
     931             :   }
     932       18105 :   output_frame->SetCallerPc(output_offset, value);
     933       18105 :   DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
     934             : 
     935             :   // The caller's frame pointer for the bottommost output frame is the same
     936             :   // as in the input frame.  For all subsequent output frames, it can be
     937             :   // read from the previous one.  Also compute and set this frame's frame
     938             :   // pointer.
     939       18105 :   output_offset -= kFPOnStackSize;
     940       18105 :   if (is_bottommost) {
     941       16729 :     value = caller_fp_;
     942             :   } else {
     943        1376 :     value = output_[frame_index - 1]->GetFp();
     944             :   }
     945       18105 :   output_frame->SetCallerFp(output_offset, value);
     946       18105 :   intptr_t fp_value = top_address + output_offset;
     947             :   output_frame->SetFp(fp_value);
     948       18105 :   if (is_topmost) {
     949       16703 :     Register fp_reg = JavaScriptFrame::fp_register();
     950       16703 :     output_frame->SetRegister(fp_reg.code(), fp_value);
     951             :   }
     952       18105 :   DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
     953             : 
     954             :   if (FLAG_enable_embedded_constant_pool) {
     955             :     // For the bottommost output frame the constant pool pointer can be gotten
     956             :     // from the input frame. For subsequent output frames, it can be read from
     957             :     // the previous frame.
     958             :     output_offset -= kPointerSize;
     959             :     if (is_bottommost) {
     960             :       value = caller_constant_pool_;
     961             :     } else {
     962             :       value = output_[frame_index - 1]->GetConstantPool();
     963             :     }
     964             :     output_frame->SetCallerConstantPool(output_offset, value);
     965             :     DebugPrintOutputSlot(value, frame_index, output_offset,
     966             :                          "caller's constant_pool\n");
     967             :   }
     968             : 
     969             :   // For the bottommost output frame the context can be gotten from the input
     970             :   // frame. For all subsequent output frames it can be gotten from the function
     971             :   // so long as we don't inline functions that need local contexts.
     972       18105 :   output_offset -= kPointerSize;
     973             : 
     974             :   // When deoptimizing into a catch block, we need to take the context
     975             :   // from just above the top of the operand stack (we push the context
     976             :   // at the entry of the try block).
     977             :   TranslatedFrame::iterator context_pos = value_iterator;
     978       18105 :   int context_input_index = input_index;
     979       18105 :   if (goto_catch_handler) {
     980           0 :     for (unsigned i = 0; i < height + 1; ++i) {
     981             :       context_pos++;
     982           0 :       context_input_index++;
     983             :     }
     984             :   }
     985             :   // Read the context from the translations.
     986       18105 :   Object* context = context_pos->GetRawValue();
     987       36210 :   if (context->IsUndefined(isolate_)) {
     988             :     // If the context was optimized away, just use the context from
     989             :     // the activation. This should only apply to Crankshaft code.
     990          14 :     CHECK(!compiled_code_->is_turbofanned());
     991             :     context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_)
     992           7 :                             : function->context();
     993             :   }
     994       18105 :   value = reinterpret_cast<intptr_t>(context);
     995             :   output_frame->SetContext(value);
     996             :   WriteValueToOutput(context, context_input_index, frame_index, output_offset,
     997       18105 :                      "context    ");
     998       18105 :   if (context == isolate_->heap()->arguments_marker()) {
     999             :     Address output_address =
    1000           0 :         reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
    1001           0 :         output_offset;
    1002           0 :     values_to_materialize_.push_back({output_address, context_pos});
    1003             :   }
    1004             :   value_iterator++;
    1005       18105 :   input_index++;
    1006             : 
    1007             :   // The function was mentioned explicitly in the BEGIN_FRAME.
    1008       18105 :   output_offset -= kPointerSize;
    1009             :   value = reinterpret_cast<intptr_t>(function);
    1010       18105 :   WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
    1011             : 
    1012       18105 :   if (trace_scope_ != nullptr) {
    1013           0 :     PrintF(trace_scope_->file(), "    -------------------------\n");
    1014             :   }
    1015             : 
    1016             :   // Translate the rest of the frame.
    1017       28446 :   for (unsigned i = 0; i < height; ++i) {
    1018       28446 :     output_offset -= kPointerSize;
    1019             :     WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
    1020       28446 :                                  output_offset);
    1021             :   }
    1022       18105 :   if (goto_catch_handler) {
    1023             :     // Write out the exception for the catch handler.
    1024           0 :     output_offset -= kPointerSize;
    1025             :     Object* exception_obj = reinterpret_cast<Object*>(
    1026           0 :         input_->GetRegister(FullCodeGenerator::result_register().code()));
    1027             :     WriteValueToOutput(exception_obj, input_index, frame_index, output_offset,
    1028           0 :                        "exception   ");
    1029           0 :     input_index++;
    1030             :   }
    1031       18105 :   CHECK_EQ(0u, output_offset);
    1032             : 
    1033             :   // Update constant pool.
    1034             :   Code* non_optimized_code = shared->code();
    1035             :   if (FLAG_enable_embedded_constant_pool) {
    1036             :     intptr_t constant_pool_value =
    1037             :         reinterpret_cast<intptr_t>(non_optimized_code->constant_pool());
    1038             :     output_frame->SetConstantPool(constant_pool_value);
    1039             :     if (is_topmost) {
    1040             :       Register constant_pool_reg =
    1041             :           JavaScriptFrame::constant_pool_pointer_register();
    1042             :       output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
    1043             :     }
    1044             :   }
    1045             : 
    1046             :   // Compute this frame's PC and state.
    1047             :   FixedArray* raw_data = non_optimized_code->deoptimization_data();
    1048             :   DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
    1049       18105 :   Address start = non_optimized_code->instruction_start();
    1050       18105 :   unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
    1051             :   unsigned pc_offset = goto_catch_handler
    1052             :                            ? catch_handler_pc_offset_
    1053       18105 :                            : FullCodeGenerator::PcField::decode(pc_and_state);
    1054       18105 :   intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
    1055             :   output_frame->SetPc(pc_value);
    1056             : 
    1057             :   // If we are going to the catch handler, then the exception lives in
    1058             :   // the accumulator.
    1059             :   BailoutState state =
    1060             :       goto_catch_handler
    1061             :           ? BailoutState::TOS_REGISTER
    1062       18105 :           : FullCodeGenerator::BailoutStateField::decode(pc_and_state);
    1063             :   output_frame->SetState(Smi::FromInt(static_cast<int>(state)));
    1064             : 
    1065             :   // Clear the context register. The context might be a de-materialized object
    1066             :   // and will be materialized by {Runtime_NotifyDeoptimized}. For additional
    1067             :   // safety we use Smi(0) instead of the potential {arguments_marker} here.
    1068       18105 :   if (is_topmost) {
    1069             :     intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
    1070       16703 :     Register context_reg = JavaScriptFrame::context_register();
    1071       16703 :     output_frame->SetRegister(context_reg.code(), context_value);
    1072             :   }
    1073             : 
    1074             :   // Set the continuation for the topmost frame.
    1075       18105 :   if (is_topmost) {
    1076       16703 :     Builtins* builtins = isolate_->builtins();
    1077             :     Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
    1078       16703 :     if (bailout_type_ == LAZY) {
    1079             :       continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
    1080       15157 :     } else if (bailout_type_ == SOFT) {
    1081             :       continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
    1082             :     } else {
    1083       14420 :       CHECK_EQ(bailout_type_, EAGER);
    1084             :     }
    1085             :     output_frame->SetContinuation(
    1086       16703 :         reinterpret_cast<intptr_t>(continuation->entry()));
    1087             :   }
    1088       18105 : }
    1089             : 
    1090      218502 : void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
    1091             :                                             int frame_index,
    1092             :                                             bool goto_catch_handler) {
    1093             :   SharedFunctionInfo* shared = translated_frame->raw_shared_info();
    1094             : 
    1095             :   TranslatedFrame::iterator value_iterator = translated_frame->begin();
    1096      109251 :   bool is_bottommost = (0 == frame_index);
    1097      109251 :   bool is_topmost = (output_count_ - 1 == frame_index);
    1098      109251 :   int input_index = 0;
    1099             : 
    1100             :   int bytecode_offset = translated_frame->node_id().ToInt();
    1101      109251 :   unsigned height = translated_frame->height();
    1102      109251 :   unsigned height_in_bytes = height * kPointerSize;
    1103             : 
    1104             :   // All tranlations for interpreted frames contain the accumulator and hence
    1105             :   // are assumed to be in bailout state {BailoutState::TOS_REGISTER}. However
    1106             :   // such a state is only supported for the topmost frame. We need to skip
    1107             :   // pushing the accumulator for any non-topmost frame.
    1108      109251 :   if (!is_topmost) height_in_bytes -= kPointerSize;
    1109             : 
    1110      109251 :   JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
    1111             :   value_iterator++;
    1112      109251 :   input_index++;
    1113      109251 :   if (trace_scope_ != NULL) {
    1114           0 :     PrintF(trace_scope_->file(), "  translating interpreted frame ");
    1115           0 :     std::unique_ptr<char[]> name = shared->DebugName()->ToCString();
    1116           0 :     PrintF(trace_scope_->file(), "%s", name.get());
    1117             :     PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d%s\n",
    1118             :            bytecode_offset, height_in_bytes,
    1119           0 :            goto_catch_handler ? " (throw)" : "");
    1120             :   }
    1121      109251 :   if (goto_catch_handler) {
    1122         505 :     bytecode_offset = catch_handler_pc_offset_;
    1123             :   }
    1124             : 
    1125             :   // The 'fixed' part of the frame consists of the incoming parameters and
    1126             :   // the part described by InterpreterFrameConstants.
    1127             :   unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared);
    1128      109251 :   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
    1129             : 
    1130             :   // Allocate and store the output frame description.
    1131             :   int parameter_count = shared->internal_formal_parameter_count() + 1;
    1132             :   FrameDescription* output_frame = new (output_frame_size)
    1133      109251 :       FrameDescription(output_frame_size, parameter_count);
    1134             :   output_frame->SetFrameType(StackFrame::INTERPRETED);
    1135             : 
    1136      109251 :   CHECK(frame_index >= 0 && frame_index < output_count_);
    1137      109287 :   CHECK_NULL(output_[frame_index]);
    1138      109251 :   output_[frame_index] = output_frame;
    1139             : 
    1140             :   // The top address of the frame is computed from the previous frame's top and
    1141             :   // this frame's size.
    1142             :   intptr_t top_address;
    1143      109251 :   if (is_bottommost) {
    1144      107813 :     top_address = caller_frame_top_ - output_frame_size;
    1145             :   } else {
    1146        4314 :     top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
    1147             :   }
    1148             :   output_frame->SetTop(top_address);
    1149             : 
    1150             :   // Compute the incoming parameter translation.
    1151             :   unsigned output_offset = output_frame_size;
    1152      233646 :   for (int i = 0; i < parameter_count; ++i) {
    1153      124395 :     output_offset -= kPointerSize;
    1154             :     WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
    1155      124395 :                                  output_offset);
    1156             :   }
    1157             : 
    1158      109251 :   if (trace_scope_ != nullptr) {
    1159           0 :     PrintF(trace_scope_->file(), "    -------------------------\n");
    1160             :   }
    1161             : 
    1162             :   // There are no translation commands for the caller's pc and fp, the
    1163             :   // context, the function, new.target and the bytecode offset.  Synthesize
    1164             :   // their values and set them up
    1165             :   // explicitly.
    1166             :   //
    1167             :   // The caller's pc for the bottommost output frame is the same as in the
    1168             :   // input frame.  For all subsequent output frames, it can be read from the
    1169             :   // previous one.  This frame's pc can be computed from the non-optimized
    1170             :   // function code and AST id of the bailout.
    1171      109251 :   output_offset -= kPCOnStackSize;
    1172             :   intptr_t value;
    1173      109251 :   if (is_bottommost) {
    1174      107813 :     value = caller_pc_;
    1175             :   } else {
    1176        1438 :     value = output_[frame_index - 1]->GetPc();
    1177             :   }
    1178      109251 :   output_frame->SetCallerPc(output_offset, value);
    1179      109251 :   DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
    1180             : 
    1181             :   // The caller's frame pointer for the bottommost output frame is the same
    1182             :   // as in the input frame.  For all subsequent output frames, it can be
    1183             :   // read from the previous one.  Also compute and set this frame's frame
    1184             :   // pointer.
    1185      109251 :   output_offset -= kFPOnStackSize;
    1186      109251 :   if (is_bottommost) {
    1187      107813 :     value = caller_fp_;
    1188             :   } else {
    1189        1438 :     value = output_[frame_index - 1]->GetFp();
    1190             :   }
    1191      109251 :   output_frame->SetCallerFp(output_offset, value);
    1192      109251 :   intptr_t fp_value = top_address + output_offset;
    1193             :   output_frame->SetFp(fp_value);
    1194      109251 :   if (is_topmost) {
    1195      107682 :     Register fp_reg = InterpretedFrame::fp_register();
    1196      107682 :     output_frame->SetRegister(fp_reg.code(), fp_value);
    1197             :   }
    1198      109251 :   DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
    1199             : 
    1200             :   if (FLAG_enable_embedded_constant_pool) {
    1201             :     // For the bottommost output frame the constant pool pointer can be gotten
    1202             :     // from the input frame. For subsequent output frames, it can be read from
    1203             :     // the previous frame.
    1204             :     output_offset -= kPointerSize;
    1205             :     if (is_bottommost) {
    1206             :       value = caller_constant_pool_;
    1207             :     } else {
    1208             :       value = output_[frame_index - 1]->GetConstantPool();
    1209             :     }
    1210             :     output_frame->SetCallerConstantPool(output_offset, value);
    1211             :     DebugPrintOutputSlot(value, frame_index, output_offset,
    1212             :                          "caller's constant_pool\n");
    1213             :   }
    1214             : 
    1215             :   // For the bottommost output frame the context can be gotten from the input
    1216             :   // frame. For all subsequent output frames it can be gotten from the function
    1217             :   // so long as we don't inline functions that need local contexts.
    1218      109251 :   output_offset -= kPointerSize;
    1219             : 
    1220             :   // When deoptimizing into a catch block, we need to take the context
    1221             :   // from a register that was specified in the handler table.
    1222             :   TranslatedFrame::iterator context_pos = value_iterator;
    1223      109251 :   int context_input_index = input_index;
    1224      109251 :   if (goto_catch_handler) {
    1225             :     // Skip to the translated value of the register specified
    1226             :     // in the handler table.
    1227        1387 :     for (int i = 0; i < catch_handler_data_ + 1; ++i) {
    1228             :       context_pos++;
    1229        1387 :       context_input_index++;
    1230             :     }
    1231             :   }
    1232             :   // Read the context from the translations.
    1233      109251 :   Object* context = context_pos->GetRawValue();
    1234      109251 :   value = reinterpret_cast<intptr_t>(context);
    1235             :   output_frame->SetContext(value);
    1236             :   WriteValueToOutput(context, context_input_index, frame_index, output_offset,
    1237      109251 :                      "context    ");
    1238      109251 :   if (context == isolate_->heap()->arguments_marker()) {
    1239             :     Address output_address =
    1240          36 :         reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
    1241          72 :         output_offset;
    1242         108 :     values_to_materialize_.push_back({output_address, context_pos});
    1243             :   }
    1244             :   value_iterator++;
    1245      109251 :   input_index++;
    1246             : 
    1247             :   // The function was mentioned explicitly in the BEGIN_FRAME.
    1248      109251 :   output_offset -= kPointerSize;
    1249             :   value = reinterpret_cast<intptr_t>(function);
    1250      109251 :   WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
    1251             : 
    1252             :   // The new.target slot is only used during function activiation which is
    1253             :   // before the first deopt point, so should never be needed. Just set it to
    1254             :   // undefined.
    1255      109251 :   output_offset -= kPointerSize;
    1256      109251 :   Object* new_target = isolate_->heap()->undefined_value();
    1257      109251 :   WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target  ");
    1258             : 
    1259             :   // Set the bytecode array pointer.
    1260      109251 :   output_offset -= kPointerSize;
    1261             :   Object* bytecode_array = shared->HasDebugInfo()
    1262             :                                ? shared->GetDebugInfo()->DebugBytecodeArray()
    1263      109251 :                                : shared->bytecode_array();
    1264             :   WriteValueToOutput(bytecode_array, 0, frame_index, output_offset,
    1265      109251 :                      "bytecode array ");
    1266             : 
    1267             :   // The bytecode offset was mentioned explicitly in the BEGIN_FRAME.
    1268      109251 :   output_offset -= kPointerSize;
    1269             :   int raw_bytecode_offset =
    1270      109251 :       BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset;
    1271             :   Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset);
    1272             :   WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset,
    1273      109251 :                      "bytecode offset ");
    1274             : 
    1275      109251 :   if (trace_scope_ != nullptr) {
    1276           0 :     PrintF(trace_scope_->file(), "    -------------------------\n");
    1277             :   }
    1278             : 
    1279             :   // Translate the rest of the interpreter registers in the frame.
    1280      656717 :   for (unsigned i = 0; i < height - 1; ++i) {
    1281      656717 :     output_offset -= kPointerSize;
    1282             :     WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
    1283      656717 :                                  output_offset);
    1284             :   }
    1285             : 
    1286             :   // Translate the accumulator register (depending on frame position).
    1287      109251 :   if (is_topmost) {
    1288             :     // For topmost frame, put the accumulator on the stack. The bailout state
    1289             :     // for interpreted frames is always set to {BailoutState::TOS_REGISTER} and
    1290             :     // the {NotifyDeoptimized} builtin pops it off the topmost frame (possibly
    1291             :     // after materialization).
    1292      107682 :     output_offset -= kPointerSize;
    1293      107682 :     if (goto_catch_handler) {
    1294             :       // If we are lazy deopting to a catch handler, we set the accumulator to
    1295             :       // the exception (which lives in the result register).
    1296             :       intptr_t accumulator_value =
    1297        1515 :           input_->GetRegister(FullCodeGenerator::result_register().code());
    1298             :       WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0,
    1299         505 :                          frame_index, output_offset, "accumulator ");
    1300             :       value_iterator++;
    1301             :     } else {
    1302             :       WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
    1303      107177 :                                    output_offset, "accumulator ");
    1304             :     }
    1305             :   } else {
    1306             :     // For non-topmost frames, skip the accumulator translation. For those
    1307             :     // frames, the return value from the callee will become the accumulator.
    1308             :     value_iterator++;
    1309        1569 :     input_index++;
    1310             :   }
    1311      109251 :   CHECK_EQ(0u, output_offset);
    1312             : 
    1313             :   // Compute this frame's PC and state. The PC will be a special builtin that
    1314             :   // continues the bytecode dispatch. Note that non-topmost and lazy-style
    1315             :   // bailout handlers also advance the bytecode offset before dispatch, hence
    1316             :   // simulating what normal handlers do upon completion of the operation.
    1317      109251 :   Builtins* builtins = isolate_->builtins();
    1318             :   Code* dispatch_builtin =
    1319      107682 :       (!is_topmost || (bailout_type_ == LAZY)) && !goto_catch_handler
    1320             :           ? builtins->builtin(Builtins::kInterpreterEnterBytecodeAdvance)
    1321      207718 :           : builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
    1322      109251 :   output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry()));
    1323             :   // Restore accumulator (TOS) register.
    1324             :   output_frame->SetState(
    1325             :       Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER)));
    1326             : 
    1327             :   // Update constant pool.
    1328             :   if (FLAG_enable_embedded_constant_pool) {
    1329             :     intptr_t constant_pool_value =
    1330             :         reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool());
    1331             :     output_frame->SetConstantPool(constant_pool_value);
    1332             :     if (is_topmost) {
    1333             :       Register constant_pool_reg =
    1334             :           InterpretedFrame::constant_pool_pointer_register();
    1335             :       output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
    1336             :     }
    1337             :   }
    1338             : 
    1339             :   // Clear the context register. The context might be a de-materialized object
    1340             :   // and will be materialized by {Runtime_NotifyDeoptimized}. For additional
    1341             :   // safety we use Smi(0) instead of the potential {arguments_marker} here.
    1342      109251 :   if (is_topmost) {
    1343             :     intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
    1344      107682 :     Register context_reg = JavaScriptFrame::context_register();
    1345      107682 :     output_frame->SetRegister(context_reg.code(), context_value);
    1346             :   }
    1347             : 
    1348             :   // Set the continuation for the topmost frame.
    1349      109251 :   if (is_topmost) {
    1350             :     Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
    1351      107682 :     if (bailout_type_ == LAZY) {
    1352             :       continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
    1353       10279 :     } else if (bailout_type_ == SOFT) {
    1354             :       continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
    1355             :     } else {
    1356        8574 :       CHECK_EQ(bailout_type_, EAGER);
    1357             :     }
    1358             :     output_frame->SetContinuation(
    1359      107682 :         reinterpret_cast<intptr_t>(continuation->entry()));
    1360             :   }
    1361      109251 : }
    1362             : 
    1363         416 : void Deoptimizer::DoComputeArgumentsAdaptorFrame(
    1364         416 :     TranslatedFrame* translated_frame, int frame_index) {
    1365             :   TranslatedFrame::iterator value_iterator = translated_frame->begin();
    1366         416 :   bool is_bottommost = (0 == frame_index);
    1367         416 :   int input_index = 0;
    1368             : 
    1369         416 :   unsigned height = translated_frame->height();
    1370         416 :   unsigned height_in_bytes = height * kPointerSize;
    1371         416 :   JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
    1372             :   value_iterator++;
    1373         416 :   input_index++;
    1374         416 :   if (trace_scope_ != NULL) {
    1375             :     PrintF(trace_scope_->file(),
    1376           0 :            "  translating arguments adaptor => height=%d\n", height_in_bytes);
    1377             :   }
    1378             : 
    1379             :   unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFixedFrameSize;
    1380         416 :   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
    1381             : 
    1382             :   // Allocate and store the output frame description.
    1383             :   int parameter_count = height;
    1384             :   FrameDescription* output_frame = new (output_frame_size)
    1385         416 :       FrameDescription(output_frame_size, parameter_count);
    1386             :   output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
    1387             : 
    1388             :   // Arguments adaptor can not be topmost.
    1389         416 :   CHECK(frame_index < output_count_ - 1);
    1390         416 :   CHECK(output_[frame_index] == NULL);
    1391         416 :   output_[frame_index] = output_frame;
    1392             : 
    1393             :   // The top address of the frame is computed from the previous frame's top and
    1394             :   // this frame's size.
    1395             :   intptr_t top_address;
    1396         416 :   if (is_bottommost) {
    1397          38 :     top_address = caller_frame_top_ - output_frame_size;
    1398             :   } else {
    1399        1134 :     top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
    1400             :   }
    1401             :   output_frame->SetTop(top_address);
    1402             : 
    1403             :   // Compute the incoming parameter translation.
    1404             :   unsigned output_offset = output_frame_size;
    1405        1549 :   for (int i = 0; i < parameter_count; ++i) {
    1406        1133 :     output_offset -= kPointerSize;
    1407             :     WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
    1408        1133 :                                  output_offset);
    1409             :   }
    1410             : 
    1411             :   // Read caller's PC from the previous frame.
    1412         416 :   output_offset -= kPCOnStackSize;
    1413             :   intptr_t value;
    1414         416 :   if (is_bottommost) {
    1415          38 :     value = caller_pc_;
    1416             :   } else {
    1417         378 :     value = output_[frame_index - 1]->GetPc();
    1418             :   }
    1419         416 :   output_frame->SetCallerPc(output_offset, value);
    1420         416 :   DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
    1421             : 
    1422             :   // Read caller's FP from the previous frame, and set this frame's FP.
    1423         416 :   output_offset -= kFPOnStackSize;
    1424         416 :   if (is_bottommost) {
    1425          38 :     value = caller_fp_;
    1426             :   } else {
    1427         378 :     value = output_[frame_index - 1]->GetFp();
    1428             :   }
    1429         416 :   output_frame->SetCallerFp(output_offset, value);
    1430         416 :   intptr_t fp_value = top_address + output_offset;
    1431             :   output_frame->SetFp(fp_value);
    1432         416 :   DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
    1433             : 
    1434             :   if (FLAG_enable_embedded_constant_pool) {
    1435             :     // Read the caller's constant pool from the previous frame.
    1436             :     output_offset -= kPointerSize;
    1437             :     if (is_bottommost) {
    1438             :       value = caller_constant_pool_;
    1439             :     } else {
    1440             :       value = output_[frame_index - 1]->GetConstantPool();
    1441             :     }
    1442             :     output_frame->SetCallerConstantPool(output_offset, value);
    1443             :     DebugPrintOutputSlot(value, frame_index, output_offset,
    1444             :                          "caller's constant_pool\n");
    1445             :   }
    1446             : 
    1447             :   // A marker value is used in place of the context.
    1448         416 :   output_offset -= kPointerSize;
    1449             :   intptr_t context = StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR);
    1450             :   output_frame->SetFrameSlot(output_offset, context);
    1451             :   DebugPrintOutputSlot(context, frame_index, output_offset,
    1452         416 :                        "context (adaptor sentinel)\n");
    1453             : 
    1454             :   // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
    1455         416 :   output_offset -= kPointerSize;
    1456             :   value = reinterpret_cast<intptr_t>(function);
    1457         416 :   WriteValueToOutput(function, 0, frame_index, output_offset, "function    ");
    1458             : 
    1459             :   // Number of incoming arguments.
    1460         416 :   output_offset -= kPointerSize;
    1461         832 :   value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
    1462             :   output_frame->SetFrameSlot(output_offset, value);
    1463         416 :   DebugPrintOutputSlot(value, frame_index, output_offset, "argc ");
    1464         416 :   if (trace_scope_ != nullptr) {
    1465           0 :     PrintF(trace_scope_->file(), "(%d)\n", height - 1);
    1466             :   }
    1467             : 
    1468             :   DCHECK(0 == output_offset);
    1469             : 
    1470         416 :   Builtins* builtins = isolate_->builtins();
    1471             :   Code* adaptor_trampoline =
    1472             :       builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
    1473             :   intptr_t pc_value = reinterpret_cast<intptr_t>(
    1474         832 :       adaptor_trampoline->instruction_start() +
    1475         832 :       isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
    1476             :   output_frame->SetPc(pc_value);
    1477             :   if (FLAG_enable_embedded_constant_pool) {
    1478             :     intptr_t constant_pool_value =
    1479             :         reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool());
    1480             :     output_frame->SetConstantPool(constant_pool_value);
    1481             :   }
    1482         416 : }
    1483             : 
    1484          50 : void Deoptimizer::DoComputeTailCallerFrame(TranslatedFrame* translated_frame,
    1485             :                                            int frame_index) {
    1486             :   SharedFunctionInfo* shared = translated_frame->raw_shared_info();
    1487             : 
    1488             :   bool is_bottommost = (0 == frame_index);
    1489             :   // Tail caller frame can't be topmost.
    1490          50 :   CHECK_NE(output_count_ - 1, frame_index);
    1491             : 
    1492          50 :   if (trace_scope_ != NULL) {
    1493           0 :     PrintF(trace_scope_->file(), "  translating tail caller frame ");
    1494           0 :     std::unique_ptr<char[]> name = shared->DebugName()->ToCString();
    1495           0 :     PrintF(trace_scope_->file(), "%s\n", name.get());
    1496             :   }
    1497             : 
    1498          50 :   if (!is_bottommost) return;
    1499             : 
    1500             :   // Drop arguments adaptor frame below current frame if it exsits.
    1501          38 :   Address fp_address = input_->GetFramePointerAddress();
    1502             :   Address adaptor_fp_address =
    1503          38 :       Memory::Address_at(fp_address + CommonFrameConstants::kCallerFPOffset);
    1504             : 
    1505          38 :   if (StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR) !=
    1506             :       Memory::intptr_at(adaptor_fp_address +
    1507             :                         CommonFrameConstants::kContextOrFrameTypeOffset)) {
    1508             :     return;
    1509             :   }
    1510             : 
    1511             :   int caller_params_count =
    1512             :       Smi::cast(
    1513             :           Memory::Object_at(adaptor_fp_address +
    1514             :                             ArgumentsAdaptorFrameConstants::kLengthOffset))
    1515          25 :           ->value();
    1516             : 
    1517             :   int callee_params_count =
    1518          25 :       function_->shared()->internal_formal_parameter_count();
    1519             : 
    1520             :   // Both caller and callee parameters count do not include receiver.
    1521          25 :   int offset = (caller_params_count - callee_params_count) * kPointerSize;
    1522             :   intptr_t new_stack_fp =
    1523          25 :       reinterpret_cast<intptr_t>(adaptor_fp_address) + offset;
    1524             : 
    1525          25 :   intptr_t new_caller_frame_top = new_stack_fp +
    1526          25 :                                   (callee_params_count + 1) * kPointerSize +
    1527          25 :                                   CommonFrameConstants::kFixedFrameSizeAboveFp;
    1528             : 
    1529             :   intptr_t adaptor_caller_pc = Memory::intptr_at(
    1530          25 :       adaptor_fp_address + CommonFrameConstants::kCallerPCOffset);
    1531             :   intptr_t adaptor_caller_fp = Memory::intptr_at(
    1532          25 :       adaptor_fp_address + CommonFrameConstants::kCallerFPOffset);
    1533             : 
    1534          25 :   if (trace_scope_ != NULL) {
    1535             :     PrintF(trace_scope_->file(),
    1536             :            "    dropping caller arguments adaptor frame: offset=%d, "
    1537             :            "fp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR
    1538             :            ", "
    1539             :            "caller sp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR "\n",
    1540             :            offset, stack_fp_, new_stack_fp, caller_frame_top_,
    1541           0 :            new_caller_frame_top);
    1542             :   }
    1543          25 :   caller_frame_top_ = new_caller_frame_top;
    1544          25 :   caller_fp_ = adaptor_caller_fp;
    1545          25 :   caller_pc_ = adaptor_caller_pc;
    1546             : }
    1547             : 
    1548         564 : void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
    1549             :                                               int frame_index) {
    1550             :   TranslatedFrame::iterator value_iterator = translated_frame->begin();
    1551         282 :   bool is_topmost = (output_count_ - 1 == frame_index);
    1552             :   // The construct frame could become topmost only if we inlined a constructor
    1553             :   // call which does a tail call (otherwise the tail callee's frame would be
    1554             :   // the topmost one). So it could only be the LAZY case.
    1555         282 :   CHECK(!is_topmost || bailout_type_ == LAZY);
    1556         282 :   int input_index = 0;
    1557             : 
    1558         282 :   Builtins* builtins = isolate_->builtins();
    1559             :   Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
    1560             :   BailoutId bailout_id = translated_frame->node_id();
    1561         282 :   unsigned height = translated_frame->height();
    1562         282 :   unsigned height_in_bytes = height * kPointerSize;
    1563             : 
    1564             :   // If the construct frame appears to be topmost we should ensure that the
    1565             :   // value of result register is preserved during continuation execution.
    1566             :   // We do this here by "pushing" the result of the constructor function to the
    1567             :   // top of the reconstructed stack and then using the
    1568             :   // BailoutState::TOS_REGISTER machinery.
    1569         282 :   if (is_topmost) {
    1570          44 :     height_in_bytes += kPointerSize;
    1571             :   }
    1572             : 
    1573         282 :   JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
    1574             :   value_iterator++;
    1575         282 :   input_index++;
    1576         282 :   if (trace_scope_ != NULL) {
    1577             :     PrintF(trace_scope_->file(),
    1578             :            "  translating construct stub => bailout_id=%d (%s), height=%d\n",
    1579             :            bailout_id.ToInt(),
    1580             :            bailout_id == BailoutId::ConstructStubCreate() ? "create" : "invoke",
    1581           0 :            height_in_bytes);
    1582             :   }
    1583             : 
    1584             :   unsigned fixed_frame_size = ConstructFrameConstants::kFixedFrameSize;
    1585         282 :   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
    1586             : 
    1587             :   // Allocate and store the output frame description.
    1588             :   FrameDescription* output_frame =
    1589         282 :       new (output_frame_size) FrameDescription(output_frame_size);
    1590             :   output_frame->SetFrameType(StackFrame::CONSTRUCT);
    1591             : 
    1592             :   // Construct stub can not be topmost.
    1593             :   DCHECK(frame_index > 0 && frame_index < output_count_);
    1594             :   DCHECK(output_[frame_index] == NULL);
    1595         282 :   output_[frame_index] = output_frame;
    1596             : 
    1597             :   // The top address of the frame is computed from the previous frame's top and
    1598             :   // this frame's size.
    1599             :   intptr_t top_address;
    1600        1128 :   top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
    1601             :   output_frame->SetTop(top_address);
    1602             : 
    1603             :   // Compute the incoming parameter translation.
    1604             :   int parameter_count = height;
    1605             :   unsigned output_offset = output_frame_size;
    1606        1006 :   for (int i = 0; i < parameter_count; ++i) {
    1607         724 :     output_offset -= kPointerSize;
    1608             :     // The allocated receiver of a construct stub frame is passed as the
    1609             :     // receiver parameter through the translation. It might be encoding
    1610             :     // a captured object, override the slot address for a captured object.
    1611             :     WriteTranslatedValueToOutput(
    1612             :         &value_iterator, &input_index, frame_index, output_offset, nullptr,
    1613         724 :         (i == 0) ? reinterpret_cast<Address>(top_address) : nullptr);
    1614             :   }
    1615             : 
    1616             :   // Read caller's PC from the previous frame.
    1617         282 :   output_offset -= kPCOnStackSize;
    1618         282 :   intptr_t callers_pc = output_[frame_index - 1]->GetPc();
    1619         282 :   output_frame->SetCallerPc(output_offset, callers_pc);
    1620         282 :   DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
    1621             : 
    1622             :   // Read caller's FP from the previous frame, and set this frame's FP.
    1623         282 :   output_offset -= kFPOnStackSize;
    1624         282 :   intptr_t value = output_[frame_index - 1]->GetFp();
    1625         282 :   output_frame->SetCallerFp(output_offset, value);
    1626         282 :   intptr_t fp_value = top_address + output_offset;
    1627             :   output_frame->SetFp(fp_value);
    1628         282 :   if (is_topmost) {
    1629          44 :     Register fp_reg = JavaScriptFrame::fp_register();
    1630          44 :     output_frame->SetRegister(fp_reg.code(), fp_value);
    1631             :   }
    1632         282 :   DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
    1633             : 
    1634             :   if (FLAG_enable_embedded_constant_pool) {
    1635             :     // Read the caller's constant pool from the previous frame.
    1636             :     output_offset -= kPointerSize;
    1637             :     value = output_[frame_index - 1]->GetConstantPool();
    1638             :     output_frame->SetCallerConstantPool(output_offset, value);
    1639             :     DebugPrintOutputSlot(value, frame_index, output_offset,
    1640             :                          "caller's constant_pool\n");
    1641             :   }
    1642             : 
    1643             :   // A marker value is used to mark the frame.
    1644         282 :   output_offset -= kPointerSize;
    1645             :   value = StackFrame::TypeToMarker(StackFrame::CONSTRUCT);
    1646             :   output_frame->SetFrameSlot(output_offset, value);
    1647             :   DebugPrintOutputSlot(value, frame_index, output_offset,
    1648         282 :                        "typed frame marker\n");
    1649             : 
    1650             :   // The context can be gotten from the previous frame.
    1651         282 :   output_offset -= kPointerSize;
    1652         282 :   value = output_[frame_index - 1]->GetContext();
    1653             :   output_frame->SetFrameSlot(output_offset, value);
    1654         282 :   DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
    1655             : 
    1656             :   // Number of incoming arguments.
    1657         282 :   output_offset -= kPointerSize;
    1658         564 :   value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
    1659             :   output_frame->SetFrameSlot(output_offset, value);
    1660         282 :   DebugPrintOutputSlot(value, frame_index, output_offset, "argc ");
    1661         282 :   if (trace_scope_ != nullptr) {
    1662           0 :     PrintF(trace_scope_->file(), "(%d)\n", height - 1);
    1663             :   }
    1664             : 
    1665         282 :   if (bailout_id == BailoutId::ConstructStubCreate()) {
    1666             :     // The function was mentioned explicitly in the CONSTRUCT_STUB_FRAME.
    1667          15 :     output_offset -= kPointerSize;
    1668             :     value = reinterpret_cast<intptr_t>(function);
    1669          15 :     WriteValueToOutput(function, 0, frame_index, output_offset, "function ");
    1670             :   } else {
    1671             :     DCHECK(bailout_id == BailoutId::ConstructStubInvoke());
    1672             :     // The newly allocated object was passed as receiver in the artificial
    1673             :     // constructor stub environment created by HEnvironment::CopyForInlining().
    1674         267 :     output_offset -= kPointerSize;
    1675         267 :     value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
    1676             :     output_frame->SetFrameSlot(output_offset, value);
    1677             :     DebugPrintOutputSlot(value, frame_index, output_offset,
    1678         267 :                          "allocated receiver\n");
    1679             :   }
    1680             : 
    1681         282 :   if (is_topmost) {
    1682             :     // Ensure the result is restored back when we return to the stub.
    1683          44 :     output_offset -= kPointerSize;
    1684          44 :     Register result_reg = FullCodeGenerator::result_register();
    1685          44 :     value = input_->GetRegister(result_reg.code());
    1686             :     output_frame->SetFrameSlot(output_offset, value);
    1687             :     DebugPrintOutputSlot(value, frame_index, output_offset,
    1688          44 :                          "constructor result\n");
    1689             : 
    1690             :     output_frame->SetState(
    1691             :         Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER)));
    1692             :   }
    1693             : 
    1694         282 :   CHECK_EQ(0u, output_offset);
    1695             : 
    1696             :   // Compute this frame's PC.
    1697             :   DCHECK(bailout_id.IsValidForConstructStub());
    1698         282 :   Address start = construct_stub->instruction_start();
    1699             :   int pc_offset =
    1700             :       bailout_id == BailoutId::ConstructStubCreate()
    1701          15 :           ? isolate_->heap()->construct_stub_create_deopt_pc_offset()->value()
    1702         549 :           : isolate_->heap()->construct_stub_invoke_deopt_pc_offset()->value();
    1703         282 :   intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
    1704             :   output_frame->SetPc(pc_value);
    1705             : 
    1706             :   // Update constant pool.
    1707             :   if (FLAG_enable_embedded_constant_pool) {
    1708             :     intptr_t constant_pool_value =
    1709             :         reinterpret_cast<intptr_t>(construct_stub->constant_pool());
    1710             :     output_frame->SetConstantPool(constant_pool_value);
    1711             :     if (is_topmost) {
    1712             :       Register constant_pool_reg =
    1713             :           JavaScriptFrame::constant_pool_pointer_register();
    1714             :       output_frame->SetRegister(constant_pool_reg.code(), fp_value);
    1715             :     }
    1716             :   }
    1717             : 
    1718             :   // Clear the context register. The context might be a de-materialized object
    1719             :   // and will be materialized by {Runtime_NotifyDeoptimized}. For additional
    1720             :   // safety we use Smi(0) instead of the potential {arguments_marker} here.
    1721         282 :   if (is_topmost) {
    1722             :     intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
    1723          44 :     Register context_reg = JavaScriptFrame::context_register();
    1724          44 :     output_frame->SetRegister(context_reg.code(), context_value);
    1725             :   }
    1726             : 
    1727             :   // Set the continuation for the topmost frame.
    1728         282 :   if (is_topmost) {
    1729          44 :     Builtins* builtins = isolate_->builtins();
    1730             :     DCHECK_EQ(LAZY, bailout_type_);
    1731             :     Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
    1732             :     output_frame->SetContinuation(
    1733          44 :         reinterpret_cast<intptr_t>(continuation->entry()));
    1734             :   }
    1735         282 : }
    1736             : 
    1737         356 : void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
    1738             :                                              int frame_index,
    1739             :                                              bool is_setter_stub_frame) {
    1740             :   TranslatedFrame::iterator value_iterator = translated_frame->begin();
    1741         356 :   bool is_topmost = (output_count_ - 1 == frame_index);
    1742             :   // The accessor frame could become topmost only if we inlined an accessor
    1743             :   // call which does a tail call (otherwise the tail callee's frame would be
    1744             :   // the topmost one). So it could only be the LAZY case.
    1745         356 :   CHECK(!is_topmost || bailout_type_ == LAZY);
    1746         356 :   int input_index = 0;
    1747             : 
    1748             :   // Skip accessor.
    1749             :   value_iterator++;
    1750         356 :   input_index++;
    1751             :   // The receiver (and the implicit return value, if any) are expected in
    1752             :   // registers by the LoadIC/StoreIC, so they don't belong to the output stack
    1753             :   // frame. This means that we have to use a height of 0.
    1754             :   unsigned height = 0;
    1755             :   unsigned height_in_bytes = height * kPointerSize;
    1756             : 
    1757             :   // If the accessor frame appears to be topmost we should ensure that the
    1758             :   // value of result register is preserved during continuation execution.
    1759             :   // We do this here by "pushing" the result of the accessor function to the
    1760             :   // top of the reconstructed stack and then using the
    1761             :   // BailoutState::TOS_REGISTER machinery.
    1762             :   // We don't need to restore the result in case of a setter call because we
    1763             :   // have to return the stored value but not the result of the setter function.
    1764         356 :   bool should_preserve_result = is_topmost && !is_setter_stub_frame;
    1765         356 :   if (should_preserve_result) {
    1766             :     height_in_bytes += kPointerSize;
    1767             :   }
    1768             : 
    1769         356 :   const char* kind = is_setter_stub_frame ? "setter" : "getter";
    1770         356 :   if (trace_scope_ != NULL) {
    1771             :     PrintF(trace_scope_->file(),
    1772           0 :            "  translating %s stub => height=%u\n", kind, height_in_bytes);
    1773             :   }
    1774             : 
    1775             :   // We need 1 stack entry for the return address and enough entries for the
    1776             :   // StackFrame::INTERNAL (FP, frame type, context, code object and constant
    1777             :   // pool (if enabled)- see MacroAssembler::EnterFrame).
    1778             :   // For a setter stub frame we need one additional entry for the implicit
    1779             :   // return value, see StoreStubCompiler::CompileStoreViaSetter.
    1780             :   unsigned fixed_frame_entries =
    1781             :       (StandardFrameConstants::kFixedFrameSize / kPointerSize) + 1 +
    1782         356 :       (is_setter_stub_frame ? 1 : 0);
    1783         356 :   unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
    1784         356 :   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
    1785             : 
    1786             :   // Allocate and store the output frame description.
    1787             :   FrameDescription* output_frame =
    1788         356 :       new (output_frame_size) FrameDescription(output_frame_size);
    1789             :   output_frame->SetFrameType(StackFrame::INTERNAL);
    1790             : 
    1791             :   // A frame for an accessor stub can not be bottommost.
    1792         356 :   CHECK(frame_index > 0 && frame_index < output_count_);
    1793         356 :   CHECK_NULL(output_[frame_index]);
    1794         356 :   output_[frame_index] = output_frame;
    1795             : 
    1796             :   // The top address of the frame is computed from the previous frame's top and
    1797             :   // this frame's size.
    1798        1424 :   intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
    1799             :   output_frame->SetTop(top_address);
    1800             : 
    1801             :   unsigned output_offset = output_frame_size;
    1802             : 
    1803             :   // Read caller's PC from the previous frame.
    1804         356 :   output_offset -= kPCOnStackSize;
    1805             :   intptr_t callers_pc = output_[frame_index - 1]->GetPc();
    1806         356 :   output_frame->SetCallerPc(output_offset, callers_pc);
    1807         356 :   DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
    1808             : 
    1809             :   // Read caller's FP from the previous frame, and set this frame's FP.
    1810         356 :   output_offset -= kFPOnStackSize;
    1811         356 :   intptr_t value = output_[frame_index - 1]->GetFp();
    1812         356 :   output_frame->SetCallerFp(output_offset, value);
    1813         356 :   intptr_t fp_value = top_address + output_offset;
    1814             :   output_frame->SetFp(fp_value);
    1815         356 :   if (is_topmost) {
    1816         151 :     Register fp_reg = JavaScriptFrame::fp_register();
    1817         151 :     output_frame->SetRegister(fp_reg.code(), fp_value);
    1818             :   }
    1819         356 :   DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
    1820             : 
    1821             :   if (FLAG_enable_embedded_constant_pool) {
    1822             :     // Read the caller's constant pool from the previous frame.
    1823             :     output_offset -= kPointerSize;
    1824             :     value = output_[frame_index - 1]->GetConstantPool();
    1825             :     output_frame->SetCallerConstantPool(output_offset, value);
    1826             :     DebugPrintOutputSlot(value, frame_index, output_offset,
    1827             :                          "caller's constant_pool\n");
    1828             :   }
    1829             : 
    1830             :   // Set the frame type.
    1831         356 :   output_offset -= kPointerSize;
    1832             :   value = StackFrame::TypeToMarker(StackFrame::INTERNAL);
    1833             :   output_frame->SetFrameSlot(output_offset, value);
    1834         356 :   DebugPrintOutputSlot(value, frame_index, output_offset, "frame type ");
    1835         356 :   if (trace_scope_ != nullptr) {
    1836           0 :     PrintF(trace_scope_->file(), "(%s sentinel)\n", kind);
    1837             :   }
    1838             : 
    1839             :   // Get Code object from accessor stub.
    1840         356 :   output_offset -= kPointerSize;
    1841             :   Builtins::Name name = is_setter_stub_frame ?
    1842             :       Builtins::kStoreIC_Setter_ForDeopt :
    1843         356 :       Builtins::kLoadIC_Getter_ForDeopt;
    1844         356 :   Code* accessor_stub = isolate_->builtins()->builtin(name);
    1845         356 :   value = reinterpret_cast<intptr_t>(accessor_stub);
    1846             :   output_frame->SetFrameSlot(output_offset, value);
    1847         356 :   DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n");
    1848             : 
    1849             :   // The context can be gotten from the previous frame.
    1850         356 :   output_offset -= kPointerSize;
    1851         356 :   value = output_[frame_index - 1]->GetContext();
    1852             :   output_frame->SetFrameSlot(output_offset, value);
    1853         356 :   DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
    1854             : 
    1855             :   // Skip receiver.
    1856             :   value_iterator++;
    1857         356 :   input_index++;
    1858             : 
    1859         356 :   if (is_setter_stub_frame) {
    1860             :     // The implicit return value was part of the artificial setter stub
    1861             :     // environment.
    1862         223 :     output_offset -= kPointerSize;
    1863             :     WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
    1864         223 :                                  output_offset);
    1865             :   }
    1866             : 
    1867         356 :   if (should_preserve_result) {
    1868             :     // Ensure the result is restored back when we return to the stub.
    1869          46 :     output_offset -= kPointerSize;
    1870          46 :     Register result_reg = FullCodeGenerator::result_register();
    1871          46 :     value = input_->GetRegister(result_reg.code());
    1872             :     output_frame->SetFrameSlot(output_offset, value);
    1873             :     DebugPrintOutputSlot(value, frame_index, output_offset,
    1874          46 :                          "accessor result\n");
    1875             : 
    1876             :     output_frame->SetState(
    1877             :         Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER)));
    1878             :   } else {
    1879             :     output_frame->SetState(
    1880             :         Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS)));
    1881             :   }
    1882             : 
    1883         356 :   CHECK_EQ(0u, output_offset);
    1884             : 
    1885             :   Smi* offset = is_setter_stub_frame ?
    1886         223 :       isolate_->heap()->setter_stub_deopt_pc_offset() :
    1887         489 :       isolate_->heap()->getter_stub_deopt_pc_offset();
    1888             :   intptr_t pc = reinterpret_cast<intptr_t>(
    1889         712 :       accessor_stub->instruction_start() + offset->value());
    1890             :   output_frame->SetPc(pc);
    1891             : 
    1892             :   // Update constant pool.
    1893             :   if (FLAG_enable_embedded_constant_pool) {
    1894             :     intptr_t constant_pool_value =
    1895             :         reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
    1896             :     output_frame->SetConstantPool(constant_pool_value);
    1897             :     if (is_topmost) {
    1898             :       Register constant_pool_reg =
    1899             :           JavaScriptFrame::constant_pool_pointer_register();
    1900             :       output_frame->SetRegister(constant_pool_reg.code(), fp_value);
    1901             :     }
    1902             :   }
    1903             : 
    1904             :   // Clear the context register. The context might be a de-materialized object
    1905             :   // and will be materialized by {Runtime_NotifyDeoptimized}. For additional
    1906             :   // safety we use Smi(0) instead of the potential {arguments_marker} here.
    1907         356 :   if (is_topmost) {
    1908             :     intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
    1909         151 :     Register context_reg = JavaScriptFrame::context_register();
    1910         151 :     output_frame->SetRegister(context_reg.code(), context_value);
    1911             :   }
    1912             : 
    1913             :   // Set the continuation for the topmost frame.
    1914         356 :   if (is_topmost) {
    1915         151 :     Builtins* builtins = isolate_->builtins();
    1916             :     DCHECK_EQ(LAZY, bailout_type_);
    1917             :     Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
    1918             :     output_frame->SetContinuation(
    1919         151 :         reinterpret_cast<intptr_t>(continuation->entry()));
    1920             :   }
    1921         356 : }
    1922             : 
    1923       53294 : void Deoptimizer::DoComputeCompiledStubFrame(TranslatedFrame* translated_frame,
    1924             :                                              int frame_index) {
    1925             :   //
    1926             :   //               FROM                                  TO
    1927             :   //    |          ....           |          |          ....           |
    1928             :   //    +-------------------------+          +-------------------------+
    1929             :   //    | JSFunction continuation |          | JSFunction continuation |
    1930             :   //    +-------------------------+          +-------------------------+
    1931             :   // |  |    saved frame (FP)     |          |    saved frame (FP)     |
    1932             :   // |  +=========================+<-fpreg   +=========================+<-fpreg
    1933             :   // |  |constant pool (if ool_cp)|          |constant pool (if ool_cp)|
    1934             :   // |  +-------------------------+          +-------------------------|
    1935             :   // |  |   JSFunction context    |          |   JSFunction context    |
    1936             :   // v  +-------------------------+          +-------------------------|
    1937             :   //    |   COMPILED_STUB marker  |          |   STUB_FAILURE marker   |
    1938             :   //    +-------------------------+          +-------------------------+
    1939             :   //    |                         |          |  caller args.arguments_ |
    1940             :   //    | ...                     |          +-------------------------+
    1941             :   //    |                         |          |  caller args.length_    |
    1942             :   //    |-------------------------|<-spreg   +-------------------------+
    1943             :   //                                         |  caller args pointer    |
    1944             :   //                                         +-------------------------+
    1945             :   //                                         |  caller stack param 1   |
    1946             :   //      parameters in registers            +-------------------------+
    1947             :   //       and spilled to stack              |           ....          |
    1948             :   //                                         +-------------------------+
    1949             :   //                                         |  caller stack param n   |
    1950             :   //                                         +-------------------------+<-spreg
    1951             :   //                                         reg = number of parameters
    1952             :   //                                         reg = failure handler address
    1953             :   //                                         reg = saved frame
    1954             :   //                                         reg = JSFunction context
    1955             :   //
    1956             :   // Caller stack params contain the register parameters to the stub first,
    1957             :   // and then, if the descriptor specifies a constant number of stack
    1958             :   // parameters, the stack parameters as well.
    1959             : 
    1960             :   TranslatedFrame::iterator value_iterator = translated_frame->begin();
    1961       26647 :   int input_index = 0;
    1962             : 
    1963       53294 :   CHECK(compiled_code_->is_hydrogen_stub());
    1964             :   int major_key = CodeStub::GetMajorKey(compiled_code_);
    1965       26647 :   CodeStubDescriptor descriptor(isolate_, compiled_code_->stub_key());
    1966             : 
    1967             :   // The output frame must have room for all pushed register parameters
    1968             :   // and the standard stack frame slots.  Include space for an argument
    1969             :   // object to the callee and optionally the space to pass the argument
    1970             :   // object to the stub failure handler.
    1971             :   int param_count = descriptor.GetRegisterParameterCount();
    1972             :   int stack_param_count = descriptor.GetStackParameterCount();
    1973             :   // The translated frame contains all of the register parameters
    1974             :   // plus the context.
    1975       53294 :   CHECK_EQ(translated_frame->height(), param_count + 1);
    1976       26647 :   CHECK_GE(param_count, 0);
    1977             : 
    1978       26647 :   int height_in_bytes = kPointerSize * (param_count + stack_param_count);
    1979             :   int fixed_frame_size = StubFailureTrampolineFrameConstants::kFixedFrameSize;
    1980       26647 :   int output_frame_size = height_in_bytes + fixed_frame_size;
    1981       26647 :   if (trace_scope_ != NULL) {
    1982             :     PrintF(trace_scope_->file(),
    1983             :            "  translating %s => StubFailureTrampolineStub, height=%d\n",
    1984             :            CodeStub::MajorName(static_cast<CodeStub::Major>(major_key)),
    1985           0 :            height_in_bytes);
    1986             :   }
    1987             : 
    1988             :   // The stub failure trampoline is a single frame.
    1989             :   FrameDescription* output_frame =
    1990       53294 :       new (output_frame_size) FrameDescription(output_frame_size);
    1991             :   output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
    1992       26647 :   CHECK_EQ(frame_index, 0);
    1993       26647 :   output_[frame_index] = output_frame;
    1994             : 
    1995             :   // The top address of the frame is computed from the previous frame's top and
    1996             :   // this frame's size.
    1997       26647 :   intptr_t top_address = caller_frame_top_ - output_frame_size;
    1998             :   output_frame->SetTop(top_address);
    1999             : 
    2000             :   // Set caller's PC (JSFunction continuation).
    2001       26647 :   unsigned output_frame_offset = output_frame_size - kFPOnStackSize;
    2002       26647 :   intptr_t value = caller_pc_;
    2003       26647 :   output_frame->SetCallerPc(output_frame_offset, value);
    2004             :   DebugPrintOutputSlot(value, frame_index, output_frame_offset,
    2005       26647 :                        "caller's pc\n");
    2006             : 
    2007             :   // Read caller's FP from the input frame, and set this frame's FP.
    2008       26647 :   value = caller_fp_;
    2009       26647 :   output_frame_offset -= kFPOnStackSize;
    2010       26647 :   output_frame->SetCallerFp(output_frame_offset, value);
    2011       26647 :   intptr_t frame_ptr = top_address + output_frame_offset;
    2012       26647 :   Register fp_reg = StubFailureTrampolineFrame::fp_register();
    2013       26647 :   output_frame->SetRegister(fp_reg.code(), frame_ptr);
    2014             :   output_frame->SetFp(frame_ptr);
    2015             :   DebugPrintOutputSlot(value, frame_index, output_frame_offset,
    2016       26647 :                        "caller's fp\n");
    2017             : 
    2018             :   if (FLAG_enable_embedded_constant_pool) {
    2019             :     // Read the caller's constant pool from the input frame.
    2020             :     value = caller_constant_pool_;
    2021             :     output_frame_offset -= kPointerSize;
    2022             :     output_frame->SetCallerConstantPool(output_frame_offset, value);
    2023             :     DebugPrintOutputSlot(value, frame_index, output_frame_offset,
    2024             :                          "caller's constant_pool\n");
    2025             :   }
    2026             : 
    2027             :   // The marker for the typed stack frame
    2028       26647 :   output_frame_offset -= kPointerSize;
    2029             :   value = StackFrame::TypeToMarker(StackFrame::STUB_FAILURE_TRAMPOLINE);
    2030             :   output_frame->SetFrameSlot(output_frame_offset, value);
    2031             :   DebugPrintOutputSlot(value, frame_index, output_frame_offset,
    2032       26647 :                        "function (stub failure sentinel)\n");
    2033             : 
    2034       26647 :   intptr_t caller_arg_count = stack_param_count;
    2035       26647 :   bool arg_count_known = !descriptor.stack_parameter_count().is_valid();
    2036             : 
    2037             :   // Build the Arguments object for the caller's parameters and a pointer to it.
    2038       26647 :   output_frame_offset -= kPointerSize;
    2039             :   int args_arguments_offset = output_frame_offset;
    2040             :   intptr_t the_hole = reinterpret_cast<intptr_t>(
    2041       26647 :       isolate_->heap()->the_hole_value());
    2042       26647 :   if (arg_count_known) {
    2043       26647 :     value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
    2044       26647 :         (caller_arg_count - 1) * kPointerSize;
    2045             :   } else {
    2046             :     value = the_hole;
    2047             :   }
    2048             : 
    2049             :   output_frame->SetFrameSlot(args_arguments_offset, value);
    2050             :   DebugPrintOutputSlot(
    2051             :       value, frame_index, args_arguments_offset,
    2052       26647 :       arg_count_known ? "args.arguments\n" : "args.arguments (the hole)\n");
    2053             : 
    2054       26647 :   output_frame_offset -= kPointerSize;
    2055             :   int length_frame_offset = output_frame_offset;
    2056       26647 :   value = arg_count_known ? caller_arg_count : the_hole;
    2057             :   output_frame->SetFrameSlot(length_frame_offset, value);
    2058             :   DebugPrintOutputSlot(
    2059             :       value, frame_index, length_frame_offset,
    2060       26647 :       arg_count_known ? "args.length\n" : "args.length (the hole)\n");
    2061             : 
    2062       26647 :   output_frame_offset -= kPointerSize;
    2063       53294 :   value = frame_ptr + StandardFrameConstants::kCallerSPOffset -
    2064       53294 :       (output_frame_size - output_frame_offset) + kPointerSize;
    2065             :   output_frame->SetFrameSlot(output_frame_offset, value);
    2066       26647 :   DebugPrintOutputSlot(value, frame_index, output_frame_offset, "args*\n");
    2067             : 
    2068             :   // Copy the register parameters to the failure frame.
    2069             :   int arguments_length_offset = -1;
    2070       70176 :   for (int i = 0; i < param_count; ++i) {
    2071       43529 :     output_frame_offset -= kPointerSize;
    2072             :     WriteTranslatedValueToOutput(&value_iterator, &input_index, 0,
    2073       43529 :                                  output_frame_offset);
    2074             : 
    2075       43529 :     if (!arg_count_known &&
    2076             :         descriptor.GetRegisterParameter(i)
    2077             :             .is(descriptor.stack_parameter_count())) {
    2078           0 :       arguments_length_offset = output_frame_offset;
    2079             :     }
    2080             :   }
    2081             : 
    2082       26647 :   Object* maybe_context = value_iterator->GetRawValue();
    2083       26647 :   CHECK(maybe_context->IsContext());
    2084       26647 :   Register context_reg = StubFailureTrampolineFrame::context_register();
    2085             :   value = reinterpret_cast<intptr_t>(maybe_context);
    2086       26647 :   output_frame->SetRegister(context_reg.code(), value);
    2087             :   ++value_iterator;
    2088             : 
    2089             :   // Copy constant stack parameters to the failure frame. If the number of stack
    2090             :   // parameters is not known in the descriptor, the arguments object is the way
    2091             :   // to access them.
    2092       26647 :   for (int i = 0; i < stack_param_count; i++) {
    2093           0 :     output_frame_offset -= kPointerSize;
    2094             :     Object** stack_parameter = reinterpret_cast<Object**>(
    2095           0 :         frame_ptr + StandardFrameConstants::kCallerSPOffset +
    2096           0 :         (stack_param_count - i - 1) * kPointerSize);
    2097           0 :     value = reinterpret_cast<intptr_t>(*stack_parameter);
    2098             :     output_frame->SetFrameSlot(output_frame_offset, value);
    2099             :     DebugPrintOutputSlot(value, frame_index, output_frame_offset,
    2100           0 :                          "stack parameter\n");
    2101             :   }
    2102             : 
    2103       26647 :   CHECK_EQ(0u, output_frame_offset);
    2104             : 
    2105       26647 :   if (!arg_count_known) {
    2106           0 :     CHECK_GE(arguments_length_offset, 0);
    2107             :     // We know it's a smi because 1) the code stub guarantees the stack
    2108             :     // parameter count is in smi range, and 2) the DoTranslateCommand in the
    2109             :     // parameter loop above translated that to a tagged value.
    2110             :     Smi* smi_caller_arg_count = reinterpret_cast<Smi*>(
    2111           0 :         output_frame->GetFrameSlot(arguments_length_offset));
    2112           0 :     caller_arg_count = smi_caller_arg_count->value();
    2113             :     output_frame->SetFrameSlot(length_frame_offset, caller_arg_count);
    2114             :     DebugPrintOutputSlot(caller_arg_count, frame_index, length_frame_offset,
    2115           0 :                          "args.length\n");
    2116             :     value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
    2117           0 :         (caller_arg_count - 1) * kPointerSize;
    2118             :     output_frame->SetFrameSlot(args_arguments_offset, value);
    2119             :     DebugPrintOutputSlot(value, frame_index, args_arguments_offset,
    2120           0 :                          "args.arguments");
    2121             :   }
    2122             : 
    2123             :   // Copy the double registers from the input into the output frame.
    2124       26647 :   CopyDoubleRegisters(output_frame);
    2125             : 
    2126             :   // Fill registers containing handler and number of parameters.
    2127       26647 :   SetPlatformCompiledStubRegisters(output_frame, &descriptor);
    2128             : 
    2129             :   // Compute this frame's PC, state, and continuation.
    2130       26647 :   Code* trampoline = NULL;
    2131       26647 :   StubFunctionMode function_mode = descriptor.function_mode();
    2132             :   StubFailureTrampolineStub(isolate_, function_mode)
    2133       79941 :       .FindCodeInCache(&trampoline);
    2134             :   DCHECK(trampoline != NULL);
    2135             :   output_frame->SetPc(reinterpret_cast<intptr_t>(
    2136       26647 :       trampoline->instruction_start()));
    2137             :   if (FLAG_enable_embedded_constant_pool) {
    2138             :     Register constant_pool_reg =
    2139             :         StubFailureTrampolineFrame::constant_pool_pointer_register();
    2140             :     intptr_t constant_pool_value =
    2141             :         reinterpret_cast<intptr_t>(trampoline->constant_pool());
    2142             :     output_frame->SetConstantPool(constant_pool_value);
    2143             :     output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
    2144             :   }
    2145             :   output_frame->SetState(
    2146             :       Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS)));
    2147             :   Code* notify_failure =
    2148       26647 :       isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles);
    2149             :   output_frame->SetContinuation(
    2150       26647 :       reinterpret_cast<intptr_t>(notify_failure->entry()));
    2151       26647 : }
    2152             : 
    2153             : 
    2154      376516 : void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
    2155             :   // Walk to the last JavaScript output frame to find out if it has
    2156             :   // adapted arguments.
    2157      503872 :   for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) {
    2158      127356 :     if (frame_index != 0) it->Advance();
    2159             :   }
    2160             :   translated_state_.Prepare(it->frame()->has_adapted_arguments(),
    2161      249160 :                             reinterpret_cast<Address>(stack_fp_));
    2162             : 
    2163      252363 :   for (auto& materialization : values_to_materialize_) {
    2164        3203 :     Handle<Object> value = materialization.value_->GetValue();
    2165             : 
    2166        3203 :     if (trace_scope_ != nullptr) {
    2167             :       PrintF("Materialization [0x%08" V8PRIxPTR "] <- 0x%08" V8PRIxPTR " ;  ",
    2168             :              reinterpret_cast<intptr_t>(materialization.output_slot_address_),
    2169           0 :              reinterpret_cast<intptr_t>(*value));
    2170           0 :       value->ShortPrint(trace_scope_->file());
    2171           0 :       PrintF(trace_scope_->file(), "\n");
    2172             :     }
    2173             : 
    2174             :     *(reinterpret_cast<intptr_t*>(materialization.output_slot_address_)) =
    2175        6406 :         reinterpret_cast<intptr_t>(*value);
    2176             :   }
    2177             : 
    2178             :   isolate_->materialized_object_store()->Remove(
    2179      124580 :       reinterpret_cast<Address>(stack_fp_));
    2180      124580 : }
    2181             : 
    2182             : 
    2183      998880 : void Deoptimizer::WriteTranslatedValueToOutput(
    2184             :     TranslatedFrame::iterator* iterator, int* input_index, int frame_index,
    2185             :     unsigned output_offset, const char* debug_hint_string,
    2186             :     Address output_address_for_materialization) {
    2187      998880 :   Object* value = (*iterator)->GetRawValue();
    2188             : 
    2189             :   WriteValueToOutput(value, *input_index, frame_index, output_offset,
    2190      998880 :                      debug_hint_string);
    2191             : 
    2192      998880 :   if (value == isolate_->heap()->arguments_marker()) {
    2193             :     Address output_address =
    2194        3167 :         reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
    2195        6334 :         output_offset;
    2196        3167 :     if (output_address_for_materialization == nullptr) {
    2197             :       output_address_for_materialization = output_address;
    2198             :     }
    2199             :     values_to_materialize_.push_back(
    2200        9501 :         {output_address_for_materialization, *iterator});
    2201             :   }
    2202             : 
    2203             :   (*iterator)++;
    2204      998880 :   (*input_index)++;
    2205      998880 : }
    2206             : 
    2207             : 
    2208     1582281 : void Deoptimizer::WriteValueToOutput(Object* value, int input_index,
    2209             :                                      int frame_index, unsigned output_offset,
    2210             :                                      const char* debug_hint_string) {
    2211     1582281 :   output_[frame_index]->SetFrameSlot(output_offset,
    2212     3164562 :                                      reinterpret_cast<intptr_t>(value));
    2213             : 
    2214     1582281 :   if (trace_scope_ != nullptr) {
    2215             :     DebugPrintOutputSlot(reinterpret_cast<intptr_t>(value), frame_index,
    2216           0 :                          output_offset, debug_hint_string);
    2217           0 :     value->ShortPrint(trace_scope_->file());
    2218           0 :     PrintF(trace_scope_->file(), "  (input #%d)\n", input_index);
    2219             :   }
    2220     1582281 : }
    2221             : 
    2222             : 
    2223      419805 : void Deoptimizer::DebugPrintOutputSlot(intptr_t value, int frame_index,
    2224             :                                        unsigned output_offset,
    2225             :                                        const char* debug_hint_string) {
    2226      419805 :   if (trace_scope_ != nullptr) {
    2227             :     Address output_address =
    2228           0 :         reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
    2229           0 :         output_offset;
    2230             :     PrintF(trace_scope_->file(),
    2231             :            "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ;  %s",
    2232             :            reinterpret_cast<intptr_t>(output_address), output_offset, value,
    2233           0 :            debug_hint_string == nullptr ? "" : debug_hint_string);
    2234             :   }
    2235      419805 : }
    2236             : 
    2237           0 : unsigned Deoptimizer::ComputeInputFrameAboveFpFixedSize() const {
    2238             :   unsigned fixed_size = CommonFrameConstants::kFixedFrameSizeAboveFp;
    2239      604908 :   if (!function_->IsSmi()) {
    2240      249160 :     fixed_size += ComputeIncomingArgumentSize(function_->shared());
    2241             :   }
    2242           0 :   return fixed_size;
    2243             : }
    2244             : 
    2245      151227 : unsigned Deoptimizer::ComputeInputFrameSize() const {
    2246             :   // The fp-to-sp delta already takes the context, constant pool pointer and the
    2247             :   // function into account so we have to avoid double counting them.
    2248             :   unsigned fixed_size_above_fp = ComputeInputFrameAboveFpFixedSize();
    2249      151227 :   unsigned result = fixed_size_above_fp + fp_to_sp_delta_;
    2250      302454 :   if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
    2251             :     unsigned stack_slots = compiled_code_->stack_slots();
    2252             :     unsigned outgoing_size =
    2253      124580 :         ComputeOutgoingArgumentSize(compiled_code_, bailout_id_);
    2254      124580 :     CHECK_EQ(fixed_size_above_fp + (stack_slots * kPointerSize) -
    2255             :                  CommonFrameConstants::kFixedFrameSizeAboveFp + outgoing_size,
    2256             :              result);
    2257             :   }
    2258      151227 :   return result;
    2259             : }
    2260             : 
    2261             : // static
    2262           0 : unsigned Deoptimizer::ComputeJavascriptFixedSize(SharedFunctionInfo* shared) {
    2263             :   // The fixed part of the frame consists of the return address, frame
    2264             :   // pointer, function, context, and all the incoming arguments.
    2265             :   return ComputeIncomingArgumentSize(shared) +
    2266       18105 :          StandardFrameConstants::kFixedFrameSize;
    2267             : }
    2268             : 
    2269             : // static
    2270           0 : unsigned Deoptimizer::ComputeInterpretedFixedSize(SharedFunctionInfo* shared) {
    2271             :   // The fixed part of the frame consists of the return address, frame
    2272             :   // pointer, function, context, new.target, bytecode offset and all the
    2273             :   // incoming arguments.
    2274             :   return ComputeIncomingArgumentSize(shared) +
    2275      109251 :          InterpreterFrameConstants::kFixedFrameSize;
    2276             : }
    2277             : 
    2278             : // static
    2279           0 : unsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo* shared) {
    2280      376516 :   return (shared->internal_formal_parameter_count() + 1) * kPointerSize;
    2281             : }
    2282             : 
    2283             : 
    2284             : // static
    2285           0 : unsigned Deoptimizer::ComputeOutgoingArgumentSize(Code* code,
    2286             :                                                   unsigned bailout_id) {
    2287             :   DeoptimizationInputData* data =
    2288             :       DeoptimizationInputData::cast(code->deoptimization_data());
    2289      249160 :   unsigned height = data->ArgumentsStackHeight(bailout_id)->value();
    2290      124580 :   return height * kPointerSize;
    2291             : }
    2292             : 
    2293    36005772 : void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
    2294             :                                                    BailoutType type,
    2295             :                                                    int max_entry_id) {
    2296             :   // We cannot run this if the serializer is enabled because this will
    2297             :   // cause us to emit relocation information for the external
    2298             :   // references. This is fine because the deoptimizer's code section
    2299             :   // isn't meant to be serialized at all.
    2300    18002886 :   CHECK(type == EAGER || type == SOFT || type == LAZY);
    2301             :   DeoptimizerData* data = isolate->deoptimizer_data();
    2302    18002886 :   int entry_count = data->deopt_entry_code_entries_[type];
    2303    35920597 :   if (max_entry_id < entry_count) return;
    2304             :   entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries);
    2305       85175 :   while (max_entry_id >= entry_count) entry_count *= 2;
    2306       85175 :   CHECK(entry_count <= Deoptimizer::kMaxNumberOfEntries);
    2307             : 
    2308       85175 :   MacroAssembler masm(isolate, NULL, 16 * KB, CodeObjectRequired::kYes);
    2309             :   masm.set_emit_debug_code(false);
    2310             :   GenerateDeoptimizationEntries(&masm, entry_count, type);
    2311             :   CodeDesc desc;
    2312       85175 :   masm.GetCode(&desc);
    2313             :   DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
    2314             : 
    2315      255525 :   MemoryChunk* chunk = data->deopt_entry_code_[type];
    2316       85175 :   CHECK(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
    2317             :         desc.instr_size);
    2318       85175 :   if (!chunk->CommitArea(desc.instr_size)) {
    2319             :     V8::FatalProcessOutOfMemory(
    2320           0 :         "Deoptimizer::EnsureCodeForDeoptimizationEntry");
    2321             :   }
    2322             :   CopyBytes(chunk->area_start(), desc.buffer,
    2323      170350 :             static_cast<size_t>(desc.instr_size));
    2324      170350 :   Assembler::FlushICache(isolate, chunk->area_start(), desc.instr_size);
    2325             : 
    2326       85175 :   data->deopt_entry_code_entries_[type] = entry_count;
    2327             : }
    2328             : 
    2329      306284 : FrameDescription::FrameDescription(uint32_t frame_size, int parameter_count)
    2330             :     : frame_size_(frame_size),
    2331             :       parameter_count_(parameter_count),
    2332             :       top_(kZapUint32),
    2333             :       pc_(kZapUint32),
    2334             :       fp_(kZapUint32),
    2335             :       context_(kZapUint32),
    2336      612568 :       constant_pool_(kZapUint32) {
    2337             :   // Zap all the registers.
    2338     5206828 :   for (int r = 0; r < Register::kNumRegisters; r++) {
    2339             :     // TODO(jbramley): It isn't safe to use kZapUint32 here. If the register
    2340             :     // isn't used before the next safepoint, the GC will try to scan it as a
    2341             :     // tagged value. kZapUint32 looks like a valid tagged pointer, but it isn't.
    2342     4900544 :     SetRegister(r, kZapUint32);
    2343             :   }
    2344             : 
    2345             :   // Zap all the slots.
    2346     3070766 :   for (unsigned o = 0; o < frame_size; o += kPointerSize) {
    2347             :     SetFrameSlot(o, kZapUint32);
    2348             :   }
    2349      306284 : }
    2350             : 
    2351   276887760 : void TranslationBuffer::Add(int32_t value) {
    2352             :   // This wouldn't handle kMinInt correctly if it ever encountered it.
    2353             :   DCHECK(value != kMinInt);
    2354             :   // Encode the sign bit in the least significant bit.
    2355   276887760 :   bool is_negative = (value < 0);
    2356   276887760 :   uint32_t bits = ((is_negative ? -value : value) << 1) |
    2357   276887760 :       static_cast<int32_t>(is_negative);
    2358             :   // Encode the individual bytes using the least significant bit of
    2359             :   // each byte to indicate whether or not more bytes follow.
    2360   283831403 :   do {
    2361   283831279 :     uint32_t next = bits >> 7;
    2362   283831279 :     contents_.push_back(((bits << 1) & 0xFF) | (next != 0));
    2363             :     bits = next;
    2364             :   } while (bits != 0);
    2365   276887884 : }
    2366             : 
    2367             : 
    2368    30257041 : int32_t TranslationIterator::Next() {
    2369             :   // Run through the bytes until we reach one with a least significant
    2370             :   // bit of zero (marks the end).
    2371             :   uint32_t bits = 0;
    2372      682248 :   for (int i = 0; true; i += 7) {
    2373             :     DCHECK(HasNext());
    2374    30939289 :     uint8_t next = buffer_->get(index_++);
    2375    30939289 :     bits |= (next >> 1) << i;
    2376    30939289 :     if ((next & 1) == 0) break;
    2377      682248 :   }
    2378             :   // The bits encode the sign in the least significant bit.
    2379    30257041 :   bool is_negative = (bits & 1) == 1;
    2380    30257041 :   int32_t result = bits >> 1;
    2381    30257041 :   return is_negative ? -result : result;
    2382             : }
    2383             : 
    2384             : 
    2385      670855 : Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) {
    2386      670855 :   Handle<ByteArray> result = factory->NewByteArray(CurrentIndex(), TENURED);
    2387      670855 :   contents_.CopyTo(result->GetDataStartAddress());
    2388      670855 :   return result;
    2389             : }
    2390             : 
    2391        2913 : void Translation::BeginConstructStubFrame(BailoutId bailout_id, int literal_id,
    2392             :                                           unsigned height) {
    2393        2913 :   buffer_->Add(CONSTRUCT_STUB_FRAME);
    2394        2913 :   buffer_->Add(bailout_id.ToInt());
    2395        2913 :   buffer_->Add(literal_id);
    2396        2913 :   buffer_->Add(height);
    2397        2913 : }
    2398             : 
    2399             : 
    2400       10316 : void Translation::BeginGetterStubFrame(int literal_id) {
    2401       10316 :   buffer_->Add(GETTER_STUB_FRAME);
    2402       10316 :   buffer_->Add(literal_id);
    2403       10316 : }
    2404             : 
    2405             : 
    2406        1263 : void Translation::BeginSetterStubFrame(int literal_id) {
    2407        1263 :   buffer_->Add(SETTER_STUB_FRAME);
    2408        1263 :   buffer_->Add(literal_id);
    2409        1263 : }
    2410             : 
    2411             : 
    2412      619006 : void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) {
    2413      619006 :   buffer_->Add(ARGUMENTS_ADAPTOR_FRAME);
    2414      619006 :   buffer_->Add(literal_id);
    2415      619006 :   buffer_->Add(height);
    2416      619006 : }
    2417             : 
    2418        5101 : void Translation::BeginTailCallerFrame(int literal_id) {
    2419        5101 :   buffer_->Add(TAIL_CALLER_FRAME);
    2420        5101 :   buffer_->Add(literal_id);
    2421        5101 : }
    2422             : 
    2423     4003527 : void Translation::BeginJSFrame(BailoutId node_id, int literal_id,
    2424             :                                unsigned height) {
    2425     4003527 :   buffer_->Add(JS_FRAME);
    2426     4003527 :   buffer_->Add(node_id.ToInt());
    2427     4003526 :   buffer_->Add(literal_id);
    2428     4003526 :   buffer_->Add(height);
    2429     4003526 : }
    2430             : 
    2431             : 
    2432     4667365 : void Translation::BeginInterpretedFrame(BailoutId bytecode_offset,
    2433             :                                         int literal_id, unsigned height) {
    2434     4667365 :   buffer_->Add(INTERPRETED_FRAME);
    2435     4667364 :   buffer_->Add(bytecode_offset.ToInt());
    2436     4667363 :   buffer_->Add(literal_id);
    2437     4667363 :   buffer_->Add(height);
    2438     4667364 : }
    2439             : 
    2440             : 
    2441       55849 : void Translation::BeginCompiledStubFrame(int height) {
    2442       55849 :   buffer_->Add(COMPILED_STUB_FRAME);
    2443       55849 :   buffer_->Add(height);
    2444       55849 : }
    2445             : 
    2446             : 
    2447        6368 : void Translation::BeginArgumentsObject(int args_length) {
    2448        6368 :   buffer_->Add(ARGUMENTS_OBJECT);
    2449        6368 :   buffer_->Add(args_length);
    2450        6368 : }
    2451             : 
    2452        2604 : void Translation::ArgumentsElements(bool is_rest) {
    2453        2604 :   buffer_->Add(ARGUMENTS_ELEMENTS);
    2454        2604 :   buffer_->Add(is_rest);
    2455        2604 : }
    2456             : 
    2457        2668 : void Translation::ArgumentsLength(bool is_rest) {
    2458        2668 :   buffer_->Add(ARGUMENTS_LENGTH);
    2459        2668 :   buffer_->Add(is_rest);
    2460        2668 : }
    2461             : 
    2462       20644 : void Translation::BeginCapturedObject(int length) {
    2463       20644 :   buffer_->Add(CAPTURED_OBJECT);
    2464       20644 :   buffer_->Add(length);
    2465       20644 : }
    2466             : 
    2467             : 
    2468        3016 : void Translation::DuplicateObject(int object_index) {
    2469        3016 :   buffer_->Add(DUPLICATED_OBJECT);
    2470        3016 :   buffer_->Add(object_index);
    2471        3016 : }
    2472             : 
    2473             : 
    2474     4157705 : void Translation::StoreRegister(Register reg) {
    2475     4157705 :   buffer_->Add(REGISTER);
    2476     4157706 :   buffer_->Add(reg.code());
    2477     4157705 : }
    2478             : 
    2479             : 
    2480      171221 : void Translation::StoreInt32Register(Register reg) {
    2481      171221 :   buffer_->Add(INT32_REGISTER);
    2482      171221 :   buffer_->Add(reg.code());
    2483      171221 : }
    2484             : 
    2485             : 
    2486         146 : void Translation::StoreUint32Register(Register reg) {
    2487         146 :   buffer_->Add(UINT32_REGISTER);
    2488         146 :   buffer_->Add(reg.code());
    2489         146 : }
    2490             : 
    2491             : 
    2492        1049 : void Translation::StoreBoolRegister(Register reg) {
    2493        1049 :   buffer_->Add(BOOL_REGISTER);
    2494        1049 :   buffer_->Add(reg.code());
    2495        1049 : }
    2496             : 
    2497          91 : void Translation::StoreFloatRegister(FloatRegister reg) {
    2498          91 :   buffer_->Add(FLOAT_REGISTER);
    2499          91 :   buffer_->Add(reg.code());
    2500          91 : }
    2501             : 
    2502       94561 : void Translation::StoreDoubleRegister(DoubleRegister reg) {
    2503       94561 :   buffer_->Add(DOUBLE_REGISTER);
    2504       94561 :   buffer_->Add(reg.code());
    2505       94561 : }
    2506             : 
    2507             : 
    2508    39915767 : void Translation::StoreStackSlot(int index) {
    2509    39915767 :   buffer_->Add(STACK_SLOT);
    2510    39915727 :   buffer_->Add(index);
    2511    39915663 : }
    2512             : 
    2513             : 
    2514      784161 : void Translation::StoreInt32StackSlot(int index) {
    2515      784161 :   buffer_->Add(INT32_STACK_SLOT);
    2516      784161 :   buffer_->Add(index);
    2517      784161 : }
    2518             : 
    2519             : 
    2520        2653 : void Translation::StoreUint32StackSlot(int index) {
    2521        2653 :   buffer_->Add(UINT32_STACK_SLOT);
    2522        2653 :   buffer_->Add(index);
    2523        2653 : }
    2524             : 
    2525             : 
    2526       70338 : void Translation::StoreBoolStackSlot(int index) {
    2527       70338 :   buffer_->Add(BOOL_STACK_SLOT);
    2528       70338 :   buffer_->Add(index);
    2529       70338 : }
    2530             : 
    2531         462 : void Translation::StoreFloatStackSlot(int index) {
    2532         462 :   buffer_->Add(FLOAT_STACK_SLOT);
    2533         462 :   buffer_->Add(index);
    2534         462 : }
    2535             : 
    2536      458378 : void Translation::StoreDoubleStackSlot(int index) {
    2537      458378 :   buffer_->Add(DOUBLE_STACK_SLOT);
    2538      458378 :   buffer_->Add(index);
    2539      458378 : }
    2540             : 
    2541             : 
    2542    64285535 : void Translation::StoreLiteral(int literal_id) {
    2543    64285535 :   buffer_->Add(LITERAL);
    2544    64285500 :   buffer_->Add(literal_id);
    2545    64285459 : }
    2546             : 
    2547             : 
    2548           0 : void Translation::StoreArgumentsObject(bool args_known,
    2549             :                                        int args_index,
    2550             :                                        int args_length) {
    2551           0 :   buffer_->Add(ARGUMENTS_OBJECT);
    2552           0 :   buffer_->Add(args_known);
    2553           0 :   buffer_->Add(args_index);
    2554           0 :   buffer_->Add(args_length);
    2555           0 : }
    2556             : 
    2557             : 
    2558     6333930 : void Translation::StoreJSFrameFunction() {
    2559             :   StoreStackSlot((StandardFrameConstants::kCallerPCOffset -
    2560             :                   StandardFrameConstants::kFunctionOffset) /
    2561     6333930 :                  kPointerSize);
    2562     6333930 : }
    2563             : 
    2564     2424982 : int Translation::NumberOfOperandsFor(Opcode opcode) {
    2565     2424982 :   switch (opcode) {
    2566             :     case GETTER_STUB_FRAME:
    2567             :     case SETTER_STUB_FRAME:
    2568             :     case DUPLICATED_OBJECT:
    2569             :     case ARGUMENTS_OBJECT:
    2570             :     case CAPTURED_OBJECT:
    2571             :     case REGISTER:
    2572             :     case INT32_REGISTER:
    2573             :     case UINT32_REGISTER:
    2574             :     case BOOL_REGISTER:
    2575             :     case FLOAT_REGISTER:
    2576             :     case DOUBLE_REGISTER:
    2577             :     case STACK_SLOT:
    2578             :     case INT32_STACK_SLOT:
    2579             :     case UINT32_STACK_SLOT:
    2580             :     case BOOL_STACK_SLOT:
    2581             :     case FLOAT_STACK_SLOT:
    2582             :     case DOUBLE_STACK_SLOT:
    2583             :     case LITERAL:
    2584             :     case COMPILED_STUB_FRAME:
    2585             :     case TAIL_CALLER_FRAME:
    2586             :       return 1;
    2587             :     case BEGIN:
    2588             :     case ARGUMENTS_ADAPTOR_FRAME:
    2589       89150 :       return 2;
    2590             :     case JS_FRAME:
    2591             :     case INTERPRETED_FRAME:
    2592             :     case CONSTRUCT_STUB_FRAME:
    2593      211764 :       return 3;
    2594             :     case ARGUMENTS_ELEMENTS:
    2595             :     case ARGUMENTS_LENGTH:
    2596             :       return 1;
    2597             :   }
    2598           0 :   FATAL("Unexpected translation type");
    2599             :   return -1;
    2600             : }
    2601             : 
    2602             : 
    2603             : #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
    2604             : 
    2605             : const char* Translation::StringFor(Opcode opcode) {
    2606             : #define TRANSLATION_OPCODE_CASE(item)   case item: return #item;
    2607             :   switch (opcode) {
    2608             :     TRANSLATION_OPCODE_LIST(TRANSLATION_OPCODE_CASE)
    2609             :   }
    2610             : #undef TRANSLATION_OPCODE_CASE
    2611             :   UNREACHABLE();
    2612             :   return "";
    2613             : }
    2614             : 
    2615             : #endif
    2616             : 
    2617             : 
    2618      187393 : Handle<FixedArray> MaterializedObjectStore::Get(Address fp) {
    2619             :   int index = StackIdToIndex(fp);
    2620      187282 :   if (index == -1) {
    2621             :     return Handle<FixedArray>::null();
    2622             :   }
    2623         111 :   Handle<FixedArray> array = GetStackEntries();
    2624         111 :   CHECK_GT(array->length(), index);
    2625             :   return Handle<FixedArray>::cast(Handle<Object>(array->get(index), isolate()));
    2626             : }
    2627             : 
    2628             : 
    2629         111 : void MaterializedObjectStore::Set(Address fp,
    2630             :                                   Handle<FixedArray> materialized_objects) {
    2631             :   int index = StackIdToIndex(fp);
    2632         111 :   if (index == -1) {
    2633             :     index = frame_fps_.length();
    2634         111 :     frame_fps_.Add(fp);
    2635             :   }
    2636             : 
    2637         111 :   Handle<FixedArray> array = EnsureStackEntries(index + 1);
    2638         111 :   array->set(index, *materialized_objects);
    2639         111 : }
    2640             : 
    2641             : 
    2642     1793713 : bool MaterializedObjectStore::Remove(Address fp) {
    2643             :   int index = StackIdToIndex(fp);
    2644     1793491 :   if (index == -1) {
    2645             :     return false;
    2646             :   }
    2647         111 :   CHECK_GE(index, 0);
    2648             : 
    2649         222 :   frame_fps_.Remove(index);
    2650         111 :   FixedArray* array = isolate()->heap()->materialized_objects();
    2651         111 :   CHECK_LT(index, array->length());
    2652         111 :   for (int i = index; i < frame_fps_.length(); i++) {
    2653           0 :     array->set(i, array->get(i + 1));
    2654             :   }
    2655         111 :   array->set(frame_fps_.length(), isolate()->heap()->undefined_value());
    2656         111 :   return true;
    2657             : }
    2658             : 
    2659             : 
    2660           0 : int MaterializedObjectStore::StackIdToIndex(Address fp) {
    2661     1980884 :   for (int i = 0; i < frame_fps_.length(); i++) {
    2662     1981328 :     if (frame_fps_[i] == fp) {
    2663             :       return i;
    2664             :     }
    2665             :   }
    2666             :   return -1;
    2667             : }
    2668             : 
    2669             : 
    2670         222 : Handle<FixedArray> MaterializedObjectStore::GetStackEntries() {
    2671         444 :   return Handle<FixedArray>(isolate()->heap()->materialized_objects());
    2672             : }
    2673             : 
    2674             : 
    2675         243 : Handle<FixedArray> MaterializedObjectStore::EnsureStackEntries(int length) {
    2676         111 :   Handle<FixedArray> array = GetStackEntries();
    2677         111 :   if (array->length() >= length) {
    2678          67 :     return array;
    2679             :   }
    2680             : 
    2681          44 :   int new_length = length > 10 ? length : 10;
    2682          44 :   if (new_length < 2 * array->length()) {
    2683             :     new_length = 2 * array->length();
    2684             :   }
    2685             : 
    2686             :   Handle<FixedArray> new_array =
    2687          44 :       isolate()->factory()->NewFixedArray(new_length, TENURED);
    2688          88 :   for (int i = 0; i < array->length(); i++) {
    2689           0 :     new_array->set(i, array->get(i));
    2690             :   }
    2691          44 :   for (int i = array->length(); i < length; i++) {
    2692          88 :     new_array->set(i, isolate()->heap()->undefined_value());
    2693             :   }
    2694             :   isolate()->heap()->SetRootMaterializedObjects(*new_array);
    2695          44 :   return new_array;
    2696             : }
    2697             : 
    2698             : namespace {
    2699             : 
    2700      264330 : Handle<Object> GetValueForDebugger(TranslatedFrame::iterator it,
    2701             :                                    Isolate* isolate) {
    2702      264330 :   if (it->GetRawValue() == isolate->heap()->arguments_marker()) {
    2703       30492 :     if (!it->IsMaterializableByDebugger()) {
    2704       12288 :       return isolate->factory()->undefined_value();
    2705             :     }
    2706             :   }
    2707      252042 :   return it->GetValue();
    2708             : }
    2709             : 
    2710             : }  // namespace
    2711             : 
    2712       48994 : DeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state,
    2713             :                                            TranslatedState::iterator frame_it,
    2714             :                                            Isolate* isolate) {
    2715             :   // If the previous frame is an adaptor frame, we will take the parameters
    2716             :   // from there.
    2717             :   TranslatedState::iterator parameter_frame = frame_it;
    2718       48994 :   if (parameter_frame != state->begin()) {
    2719             :     parameter_frame--;
    2720             :   }
    2721             :   int parameter_count;
    2722       48994 :   if (parameter_frame->kind() == TranslatedFrame::kArgumentsAdaptor) {
    2723        4446 :     parameter_count = parameter_frame->height() - 1;  // Ignore the receiver.
    2724             :   } else {
    2725             :     parameter_frame = frame_it;
    2726             :     parameter_count =
    2727             :         frame_it->shared_info()->internal_formal_parameter_count();
    2728             :   }
    2729             :   TranslatedFrame::iterator parameter_it = parameter_frame->begin();
    2730             :   parameter_it++;  // Skip the function.
    2731             :   parameter_it++;  // Skip the receiver.
    2732             : 
    2733             :   // Figure out whether there is a construct stub frame on top of
    2734             :   // the parameter frame.
    2735             :   has_construct_stub_ =
    2736       57809 :       parameter_frame != state->begin() &&
    2737       57809 :       (parameter_frame - 1)->kind() == TranslatedFrame::kConstructStub;
    2738             : 
    2739       48994 :   if (frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
    2740             :     source_position_ = Deoptimizer::ComputeSourcePositionFromBytecodeArray(
    2741       30961 :         *frame_it->shared_info(), frame_it->node_id());
    2742             :   } else {
    2743             :     DCHECK_EQ(TranslatedFrame::kFunction, frame_it->kind());
    2744             :     source_position_ = Deoptimizer::ComputeSourcePositionFromBaselineCode(
    2745       18033 :         *frame_it->shared_info(), frame_it->node_id());
    2746             :   }
    2747             : 
    2748             :   TranslatedFrame::iterator value_it = frame_it->begin();
    2749             :   // Get the function. Note that this might materialize the function.
    2750             :   // In case the debugger mutates this value, we should deoptimize
    2751             :   // the function and remember the value in the materialized value store.
    2752       48994 :   function_ = Handle<JSFunction>::cast(value_it->GetValue());
    2753             : 
    2754       48994 :   parameters_.resize(static_cast<size_t>(parameter_count));
    2755       89995 :   for (int i = 0; i < parameter_count; i++) {
    2756       41001 :     Handle<Object> parameter = GetValueForDebugger(parameter_it, isolate);
    2757             :     SetParameter(i, parameter);
    2758             :     parameter_it++;
    2759             :   }
    2760             : 
    2761             :   // Skip the function, the receiver and the arguments.
    2762             :   int skip_count =
    2763       48994 :       frame_it->shared_info()->internal_formal_parameter_count() + 2;
    2764             :   TranslatedFrame::iterator stack_it = frame_it->begin();
    2765      188777 :   for (int i = 0; i < skip_count; i++) {
    2766             :     stack_it++;
    2767             :   }
    2768             : 
    2769             :   // Get the context.
    2770       48994 :   context_ = GetValueForDebugger(stack_it, isolate);
    2771             :   stack_it++;
    2772             : 
    2773             :   // Get the expression stack.
    2774       48994 :   int stack_height = frame_it->height();
    2775       48994 :   if (frame_it->kind() == TranslatedFrame::kFunction ||
    2776             :       frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
    2777             :     // For full-code frames, we should not count the context.
    2778             :     // For interpreter frames, we should not count the accumulator.
    2779             :     // TODO(jarin): Clean up the indexing in translated frames.
    2780       48994 :     stack_height--;
    2781             :   }
    2782       48994 :   expression_stack_.resize(static_cast<size_t>(stack_height));
    2783      223329 :   for (int i = 0; i < stack_height; i++) {
    2784      174335 :     Handle<Object> expression = GetValueForDebugger(stack_it, isolate);
    2785             :     SetExpression(i, expression);
    2786             :     stack_it++;
    2787             :   }
    2788             : 
    2789             :   // For interpreter frame, skip the accumulator.
    2790       48994 :   if (frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
    2791             :     stack_it++;
    2792             :   }
    2793       48994 :   CHECK(stack_it == frame_it->end());
    2794       48994 : }
    2795             : 
    2796             : 
    2797          41 : Deoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, Address pc) {
    2798          82 :   CHECK(code->instruction_start() <= pc && pc <= code->instruction_end());
    2799             :   SourcePosition last_position = SourcePosition::Unknown();
    2800             :   DeoptimizeReason last_reason = DeoptimizeReason::kNoReason;
    2801             :   int last_deopt_id = kNoDeoptimizationId;
    2802             :   int mask = RelocInfo::ModeMask(RelocInfo::DEOPT_REASON) |
    2803             :              RelocInfo::ModeMask(RelocInfo::DEOPT_ID) |
    2804             :              RelocInfo::ModeMask(RelocInfo::DEOPT_SCRIPT_OFFSET) |
    2805             :              RelocInfo::ModeMask(RelocInfo::DEOPT_INLINING_ID);
    2806         221 :   for (RelocIterator it(code, mask); !it.done(); it.next()) {
    2807         567 :     RelocInfo* info = it.rinfo();
    2808         207 :     if (info->pc() >= pc) break;
    2809         180 :     if (info->rmode() == RelocInfo::DEOPT_SCRIPT_OFFSET) {
    2810          60 :       int script_offset = static_cast<int>(info->data());
    2811          60 :       it.next();
    2812             :       DCHECK(it.rinfo()->rmode() == RelocInfo::DEOPT_INLINING_ID);
    2813          60 :       int inlining_id = static_cast<int>(it.rinfo()->data());
    2814             :       last_position = SourcePosition(script_offset, inlining_id);
    2815         120 :     } else if (info->rmode() == RelocInfo::DEOPT_ID) {
    2816          60 :       last_deopt_id = static_cast<int>(info->data());
    2817          60 :     } else if (info->rmode() == RelocInfo::DEOPT_REASON) {
    2818          60 :       last_reason = static_cast<DeoptimizeReason>(info->data());
    2819             :     }
    2820             :   }
    2821          41 :   return DeoptInfo(last_position, last_reason, last_deopt_id);
    2822             : }
    2823             : 
    2824             : 
    2825             : // static
    2826       18033 : int Deoptimizer::ComputeSourcePositionFromBaselineCode(
    2827             :     SharedFunctionInfo* shared, BailoutId node_id) {
    2828             :   DCHECK(shared->HasBaselineCode());
    2829             :   Code* code = shared->code();
    2830             :   FixedArray* raw_data = code->deoptimization_data();
    2831             :   DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
    2832       18033 :   unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, shared);
    2833             :   int code_offset =
    2834       18033 :       static_cast<int>(FullCodeGenerator::PcField::decode(pc_and_state));
    2835       18033 :   return AbstractCode::cast(code)->SourcePosition(code_offset);
    2836             : }
    2837             : 
    2838             : // static
    2839           0 : int Deoptimizer::ComputeSourcePositionFromBytecodeArray(
    2840             :     SharedFunctionInfo* shared, BailoutId node_id) {
    2841             :   DCHECK(shared->HasBytecodeArray());
    2842             :   return AbstractCode::cast(shared->bytecode_array())
    2843       30961 :       ->SourcePosition(node_id.ToInt());
    2844             : }
    2845             : 
    2846             : // static
    2847           0 : TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container,
    2848             :                                                     int length,
    2849             :                                                     int object_index) {
    2850             :   TranslatedValue slot(container, kArgumentsObject);
    2851         757 :   slot.materialization_info_ = {object_index, length};
    2852           0 :   return slot;
    2853             : }
    2854             : 
    2855             : // static
    2856           0 : TranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container,
    2857             :                                                    int length,
    2858             :                                                    int object_index) {
    2859             :   TranslatedValue slot(container, kCapturedObject);
    2860       15607 :   slot.materialization_info_ = {object_index, length};
    2861           0 :   return slot;
    2862             : }
    2863             : 
    2864             : 
    2865             : // static
    2866           0 : TranslatedValue TranslatedValue::NewDuplicateObject(TranslatedState* container,
    2867             :                                                     int id) {
    2868             :   TranslatedValue slot(container, kDuplicatedObject);
    2869       27789 :   slot.materialization_info_ = {id, -1};
    2870           0 :   return slot;
    2871             : }
    2872             : 
    2873             : 
    2874             : // static
    2875           0 : TranslatedValue TranslatedValue::NewFloat(TranslatedState* container,
    2876             :                                           Float32 value) {
    2877             :   TranslatedValue slot(container, kFloat);
    2878         280 :   slot.float_value_ = value;
    2879           0 :   return slot;
    2880             : }
    2881             : 
    2882             : // static
    2883           0 : TranslatedValue TranslatedValue::NewDouble(TranslatedState* container,
    2884             :                                            Float64 value) {
    2885             :   TranslatedValue slot(container, kDouble);
    2886      143057 :   slot.double_value_ = value;
    2887           0 :   return slot;
    2888             : }
    2889             : 
    2890             : 
    2891             : // static
    2892           0 : TranslatedValue TranslatedValue::NewInt32(TranslatedState* container,
    2893             :                                           int32_t value) {
    2894             :   TranslatedValue slot(container, kInt32);
    2895      140250 :   slot.int32_value_ = value;
    2896           0 :   return slot;
    2897             : }
    2898             : 
    2899             : 
    2900             : // static
    2901           0 : TranslatedValue TranslatedValue::NewUInt32(TranslatedState* container,
    2902             :                                            uint32_t value) {
    2903             :   TranslatedValue slot(container, kUInt32);
    2904          33 :   slot.uint32_value_ = value;
    2905           0 :   return slot;
    2906             : }
    2907             : 
    2908             : 
    2909             : // static
    2910           0 : TranslatedValue TranslatedValue::NewBool(TranslatedState* container,
    2911             :                                          uint32_t value) {
    2912             :   TranslatedValue slot(container, kBoolBit);
    2913          68 :   slot.uint32_value_ = value;
    2914           0 :   return slot;
    2915             : }
    2916             : 
    2917             : 
    2918             : // static
    2919           0 : TranslatedValue TranslatedValue::NewTagged(TranslatedState* container,
    2920             :                                            Object* literal) {
    2921             :   TranslatedValue slot(container, kTagged);
    2922     2398258 :   slot.raw_literal_ = literal;
    2923           0 :   return slot;
    2924             : }
    2925             : 
    2926             : 
    2927             : // static
    2928           0 : TranslatedValue TranslatedValue::NewInvalid(TranslatedState* container) {
    2929           0 :   return TranslatedValue(container, kInvalid);
    2930             : }
    2931             : 
    2932             : 
    2933     2428803 : Isolate* TranslatedValue::isolate() const { return container_->isolate(); }
    2934             : 
    2935             : 
    2936           0 : Object* TranslatedValue::raw_literal() const {
    2937             :   DCHECK_EQ(kTagged, kind());
    2938     3603783 :   return raw_literal_;
    2939             : }
    2940             : 
    2941             : 
    2942           0 : int32_t TranslatedValue::int32_value() const {
    2943             :   DCHECK_EQ(kInt32, kind());
    2944       37654 :   return int32_value_;
    2945             : }
    2946             : 
    2947             : 
    2948           0 : uint32_t TranslatedValue::uint32_value() const {
    2949             :   DCHECK(kind() == kUInt32 || kind() == kBoolBit);
    2950         148 :   return uint32_value_;
    2951             : }
    2952             : 
    2953           0 : Float32 TranslatedValue::float_value() const {
    2954             :   DCHECK_EQ(kFloat, kind());
    2955         280 :   return float_value_;
    2956             : }
    2957             : 
    2958           0 : Float64 TranslatedValue::double_value() const {
    2959             :   DCHECK_EQ(kDouble, kind());
    2960       22993 :   return double_value_;
    2961             : }
    2962             : 
    2963             : 
    2964           0 : int TranslatedValue::object_length() const {
    2965             :   DCHECK(kind() == kArgumentsObject || kind() == kCapturedObject);
    2966       20287 :   return materialization_info_.length_;
    2967             : }
    2968             : 
    2969             : 
    2970           0 : int TranslatedValue::object_index() const {
    2971             :   DCHECK(kind() == kArgumentsObject || kind() == kCapturedObject ||
    2972             :          kind() == kDuplicatedObject);
    2973        1692 :   return materialization_info_.id_;
    2974             : }
    2975             : 
    2976             : 
    2977     2960218 : Object* TranslatedValue::GetRawValue() const {
    2978             :   // If we have a value, return it.
    2979             :   Handle<Object> result_handle;
    2980     1589769 :   if (value_.ToHandle(&result_handle)) {
    2981      219320 :     return *result_handle;
    2982             :   }
    2983             : 
    2984             :   // Otherwise, do a best effort to get the value without allocation.
    2985     1370449 :   switch (kind()) {
    2986             :     case kTagged:
    2987     1275701 :       return raw_literal();
    2988             : 
    2989             :     case kInt32: {
    2990             :       bool is_smi = Smi::IsValid(int32_value());
    2991             :       if (is_smi) {
    2992       37654 :         return Smi::FromInt(int32_value());
    2993             :       }
    2994             :       break;
    2995             :     }
    2996             : 
    2997             :     case kUInt32: {
    2998          54 :       bool is_smi = (uint32_value() <= static_cast<uintptr_t>(Smi::kMaxValue));
    2999          54 :       if (is_smi) {
    3000           7 :         return Smi::FromInt(static_cast<int32_t>(uint32_value()));
    3001             :       }
    3002             :       break;
    3003             :     }
    3004             : 
    3005             :     case kBoolBit: {
    3006          68 :       if (uint32_value() == 0) {
    3007          52 :         return isolate()->heap()->false_value();
    3008             :       } else {
    3009          16 :         CHECK_EQ(1U, uint32_value());
    3010          16 :         return isolate()->heap()->true_value();
    3011             :       }
    3012             :     }
    3013             : 
    3014             :     default:
    3015             :       break;
    3016             :   }
    3017             : 
    3018             :   // If we could not get the value without allocation, return the arguments
    3019             :   // marker.
    3020       57019 :   return isolate()->heap()->arguments_marker();
    3021             : }
    3022             : 
    3023             : 
    3024      395632 : Handle<Object> TranslatedValue::GetValue() {
    3025             :   Handle<Object> result;
    3026             :   // If we already have a value, then get it.
    3027      351172 :   if (value_.ToHandle(&result)) return result;
    3028             : 
    3029             :   // Otherwise we have to materialize.
    3030       44460 :   switch (kind()) {
    3031             :     case TranslatedValue::kTagged:
    3032             :     case TranslatedValue::kInt32:
    3033             :     case TranslatedValue::kUInt32:
    3034             :     case TranslatedValue::kBoolBit:
    3035             :     case TranslatedValue::kFloat:
    3036             :     case TranslatedValue::kDouble: {
    3037       42780 :       MaterializeSimple();
    3038             :       return value_.ToHandleChecked();
    3039             :     }
    3040             : 
    3041             :     case TranslatedValue::kArgumentsObject:
    3042             :     case TranslatedValue::kCapturedObject:
    3043             :     case TranslatedValue::kDuplicatedObject:
    3044        1680 :       return container_->MaterializeObjectAt(object_index());
    3045             : 
    3046             :     case TranslatedValue::kInvalid:
    3047           0 :       FATAL("unexpected case");
    3048             :       return Handle<Object>::null();
    3049             :   }
    3050             : 
    3051           0 :   FATAL("internal error: value missing");
    3052             :   return Handle<Object>::null();
    3053             : }
    3054             : 
    3055             : 
    3056       75485 : void TranslatedValue::MaterializeSimple() {
    3057             :   // If we already have materialized, return.
    3058       52186 :   if (!value_.is_null()) return;
    3059             : 
    3060       43634 :   Object* raw_value = GetRawValue();
    3061       43634 :   if (raw_value != isolate()->heap()->arguments_marker()) {
    3062             :     // We can get the value without allocation, just return it here.
    3063       20335 :     value_ = Handle<Object>(raw_value, isolate());
    3064       20335 :     return;
    3065             :   }
    3066             : 
    3067       23299 :   switch (kind()) {
    3068             :     case kInt32:
    3069           0 :       value_ = Handle<Object>(isolate()->factory()->NewNumber(int32_value()));
    3070           0 :       return;
    3071             : 
    3072             :     case kUInt32:
    3073          26 :       value_ = Handle<Object>(isolate()->factory()->NewNumber(uint32_value()));
    3074          26 :       return;
    3075             : 
    3076             :     case kFloat: {
    3077         280 :       double scalar_value = float_value().get_scalar();
    3078         280 :       value_ = Handle<Object>(isolate()->factory()->NewNumber(scalar_value));
    3079         280 :       return;
    3080             :     }
    3081             : 
    3082             :     case kDouble: {
    3083       22993 :       double scalar_value = double_value().get_scalar();
    3084       22993 :       value_ = Handle<Object>(isolate()->factory()->NewNumber(scalar_value));
    3085       22993 :       return;
    3086             :     }
    3087             : 
    3088             :     case kCapturedObject:
    3089             :     case kDuplicatedObject:
    3090             :     case kArgumentsObject:
    3091             :     case kInvalid:
    3092             :     case kTagged:
    3093             :     case kBoolBit:
    3094           0 :       FATAL("internal error: unexpected materialization.");
    3095             :       break;
    3096             :   }
    3097             : }
    3098             : 
    3099             : 
    3100       35658 : bool TranslatedValue::IsMaterializedObject() const {
    3101       35658 :   switch (kind()) {
    3102             :     case kCapturedObject:
    3103             :     case kDuplicatedObject:
    3104             :     case kArgumentsObject:
    3105             :       return true;
    3106             :     default:
    3107       35144 :       return false;
    3108             :   }
    3109             : }
    3110             : 
    3111       30492 : bool TranslatedValue::IsMaterializableByDebugger() const {
    3112             :   // At the moment, we only allow materialization of doubles.
    3113           0 :   return (kind() == kDouble);
    3114             : }
    3115             : 
    3116     4639823 : int TranslatedValue::GetChildrenCount() const {
    3117     4640043 :   if (kind() == kCapturedObject || kind() == kArgumentsObject) {
    3118           0 :     return object_length();
    3119             :   } else {
    3120             :     return 0;
    3121             :   }
    3122             : }
    3123             : 
    3124             : 
    3125           0 : uint32_t TranslatedState::GetUInt32Slot(Address fp, int slot_offset) {
    3126      138328 :   Address address = fp + slot_offset;
    3127             : #if V8_TARGET_BIG_ENDIAN && V8_HOST_ARCH_64_BIT
    3128             :   return Memory::uint32_at(address + kIntSize);
    3129             : #else
    3130      138328 :   return Memory::uint32_at(address);
    3131             : #endif
    3132             : }
    3133             : 
    3134           0 : Float32 TranslatedState::GetFloatSlot(Address fp, int slot_offset) {
    3135             : #if !V8_TARGET_ARCH_S390X && !V8_TARGET_ARCH_PPC64
    3136           0 :   return Float32::FromBits(GetUInt32Slot(fp, slot_offset));
    3137             : #else
    3138             :   return Float32::FromBits(Memory::uint32_at(fp + slot_offset));
    3139             : #endif
    3140             : }
    3141             : 
    3142           0 : Float64 TranslatedState::GetDoubleSlot(Address fp, int slot_offset) {
    3143      142257 :   return Float64::FromBits(Memory::uint64_at(fp + slot_offset));
    3144             : }
    3145             : 
    3146     2680667 : void TranslatedValue::Handlify() {
    3147     2680667 :   if (kind() == kTagged) {
    3148     2328082 :     value_ = Handle<Object>(raw_literal(), isolate());
    3149     2328082 :     raw_literal_ = nullptr;
    3150             :   }
    3151     2680667 : }
    3152             : 
    3153             : 
    3154           0 : TranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id,
    3155             :                                          SharedFunctionInfo* shared_info,
    3156             :                                          int height) {
    3157             :   TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info,
    3158             :                         height);
    3159       80982 :   frame.node_id_ = node_id;
    3160           0 :   return frame;
    3161             : }
    3162             : 
    3163             : 
    3164           0 : TranslatedFrame TranslatedFrame::InterpretedFrame(
    3165             :     BailoutId bytecode_offset, SharedFunctionInfo* shared_info, int height) {
    3166             :   TranslatedFrame frame(kInterpretedFunction, shared_info->GetIsolate(),
    3167             :                         shared_info, height);
    3168      179200 :   frame.node_id_ = bytecode_offset;
    3169           0 :   return frame;
    3170             : }
    3171             : 
    3172             : 
    3173           0 : TranslatedFrame TranslatedFrame::AccessorFrame(
    3174             :     Kind kind, SharedFunctionInfo* shared_info) {
    3175             :   DCHECK(kind == kSetter || kind == kGetter);
    3176           0 :   return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info);
    3177             : }
    3178             : 
    3179             : 
    3180           0 : TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame(
    3181             :     SharedFunctionInfo* shared_info, int height) {
    3182             :   return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(),
    3183           0 :                          shared_info, height);
    3184             : }
    3185             : 
    3186           0 : TranslatedFrame TranslatedFrame::TailCallerFrame(
    3187             :     SharedFunctionInfo* shared_info) {
    3188             :   return TranslatedFrame(kTailCallerFunction, shared_info->GetIsolate(),
    3189           0 :                          shared_info, 0);
    3190             : }
    3191             : 
    3192           0 : TranslatedFrame TranslatedFrame::ConstructStubFrame(
    3193             :     BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) {
    3194             :   TranslatedFrame frame(kConstructStub, shared_info->GetIsolate(), shared_info,
    3195             :                         height);
    3196       13982 :   frame.node_id_ = bailout_id;
    3197           0 :   return frame;
    3198             : }
    3199             : 
    3200             : 
    3201      335904 : int TranslatedFrame::GetValueCount() {
    3202      335904 :   switch (kind()) {
    3203             :     case kFunction: {
    3204             :       int parameter_count =
    3205      161964 :           raw_shared_info_->internal_formal_parameter_count() + 1;
    3206             :       // + 1 for function.
    3207       80982 :       return height_ + parameter_count + 1;
    3208             :     }
    3209             : 
    3210             :     case kInterpretedFunction: {
    3211             :       int parameter_count =
    3212      358400 :           raw_shared_info_->internal_formal_parameter_count() + 1;
    3213             :       // + 2 for function and context.
    3214      179200 :       return height_ + parameter_count + 2;
    3215             :     }
    3216             : 
    3217             :     case kGetter:
    3218             :       return 2;  // Function and receiver.
    3219             : 
    3220             :     case kSetter:
    3221         223 :       return 3;  // Function, receiver and the value to set.
    3222             : 
    3223             :     case kArgumentsAdaptor:
    3224             :     case kConstructStub:
    3225       46566 :       return 1 + height_;
    3226             : 
    3227             :     case kTailCallerFunction:
    3228          82 :       return 1;  // Function.
    3229             : 
    3230             :     case kCompiledStub:
    3231       26647 :       return height_;
    3232             : 
    3233             :     case kInvalid:
    3234           0 :       UNREACHABLE();
    3235             :       break;
    3236             :   }
    3237           0 :   UNREACHABLE();
    3238             :   return -1;
    3239             : }
    3240             : 
    3241             : 
    3242      309257 : void TranslatedFrame::Handlify() {
    3243      309257 :   if (raw_shared_info_ != nullptr) {
    3244      309257 :     shared_info_ = Handle<SharedFunctionInfo>(raw_shared_info_);
    3245      309257 :     raw_shared_info_ = nullptr;
    3246             :   }
    3247     2989924 :   for (auto& value : values_) {
    3248     2680667 :     value.Handlify();
    3249             :   }
    3250      309257 : }
    3251             : 
    3252             : 
    3253      335904 : TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
    3254             :     TranslationIterator* iterator, FixedArray* literal_array, Address fp,
    3255             :     FILE* trace_file) {
    3256             :   Translation::Opcode opcode =
    3257      335904 :       static_cast<Translation::Opcode>(iterator->Next());
    3258      335904 :   switch (opcode) {
    3259             :     case Translation::JS_FRAME: {
    3260       80982 :       BailoutId node_id = BailoutId(iterator->Next());
    3261             :       SharedFunctionInfo* shared_info =
    3262       80982 :           SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
    3263       80982 :       int height = iterator->Next();
    3264       80982 :       if (trace_file != nullptr) {
    3265           0 :         std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
    3266           0 :         PrintF(trace_file, "  reading input frame %s", name.get());
    3267           0 :         int arg_count = shared_info->internal_formal_parameter_count() + 1;
    3268             :         PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n",
    3269           0 :                node_id.ToInt(), arg_count, height);
    3270             :       }
    3271             :       return TranslatedFrame::JSFrame(node_id, shared_info, height);
    3272             :     }
    3273             : 
    3274             :     case Translation::INTERPRETED_FRAME: {
    3275      179200 :       BailoutId bytecode_offset = BailoutId(iterator->Next());
    3276             :       SharedFunctionInfo* shared_info =
    3277      179200 :           SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
    3278      179200 :       int height = iterator->Next();
    3279      179200 :       if (trace_file != nullptr) {
    3280           0 :         std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
    3281           0 :         PrintF(trace_file, "  reading input frame %s", name.get());
    3282           0 :         int arg_count = shared_info->internal_formal_parameter_count() + 1;
    3283             :         PrintF(trace_file,
    3284             :                " => bytecode_offset=%d, args=%d, height=%d; inputs:\n",
    3285           0 :                bytecode_offset.ToInt(), arg_count, height);
    3286             :       }
    3287             :       return TranslatedFrame::InterpretedFrame(bytecode_offset, shared_info,
    3288             :                                                height);
    3289             :     }
    3290             : 
    3291             :     case Translation::ARGUMENTS_ADAPTOR_FRAME: {
    3292             :       SharedFunctionInfo* shared_info =
    3293       32584 :           SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
    3294       32584 :       int height = iterator->Next();
    3295       32584 :       if (trace_file != nullptr) {
    3296           0 :         std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
    3297           0 :         PrintF(trace_file, "  reading arguments adaptor frame %s", name.get());
    3298           0 :         PrintF(trace_file, " => height=%d; inputs:\n", height);
    3299             :       }
    3300             :       return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height);
    3301             :     }
    3302             : 
    3303             :     case Translation::TAIL_CALLER_FRAME: {
    3304             :       SharedFunctionInfo* shared_info =
    3305          82 :           SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
    3306          82 :       if (trace_file != nullptr) {
    3307           0 :         std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
    3308             :         PrintF(trace_file, "  reading tail caller frame marker %s\n",
    3309           0 :                name.get());
    3310             :       }
    3311             :       return TranslatedFrame::TailCallerFrame(shared_info);
    3312             :     }
    3313             : 
    3314             :     case Translation::CONSTRUCT_STUB_FRAME: {
    3315       13982 :       BailoutId bailout_id = BailoutId(iterator->Next());
    3316             :       SharedFunctionInfo* shared_info =
    3317       13982 :           SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
    3318       13982 :       int height = iterator->Next();
    3319       13982 :       if (trace_file != nullptr) {
    3320           0 :         std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
    3321           0 :         PrintF(trace_file, "  reading construct stub frame %s", name.get());
    3322             :         PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n",
    3323           0 :                bailout_id.ToInt(), height);
    3324             :       }
    3325             :       return TranslatedFrame::ConstructStubFrame(bailout_id, shared_info,
    3326             :                                                  height);
    3327             :     }
    3328             : 
    3329             :     case Translation::GETTER_STUB_FRAME: {
    3330             :       SharedFunctionInfo* shared_info =
    3331        2204 :           SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
    3332        2204 :       if (trace_file != nullptr) {
    3333           0 :         std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
    3334           0 :         PrintF(trace_file, "  reading getter frame %s; inputs:\n", name.get());
    3335             :       }
    3336             :       return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter,
    3337             :                                             shared_info);
    3338             :     }
    3339             : 
    3340             :     case Translation::SETTER_STUB_FRAME: {
    3341             :       SharedFunctionInfo* shared_info =
    3342         223 :           SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
    3343         223 :       if (trace_file != nullptr) {
    3344           0 :         std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString();
    3345           0 :         PrintF(trace_file, "  reading setter frame %s; inputs:\n", name.get());
    3346             :       }
    3347             :       return TranslatedFrame::AccessorFrame(TranslatedFrame::kSetter,
    3348             :                                             shared_info);
    3349             :     }
    3350             : 
    3351             :     case Translation::COMPILED_STUB_FRAME: {
    3352       26647 :       int height = iterator->Next();
    3353       26647 :       if (trace_file != nullptr) {
    3354             :         PrintF(trace_file,
    3355           0 :                "  reading compiler stub frame => height=%d; inputs:\n", height);
    3356             :       }
    3357             :       return TranslatedFrame::CompiledStubFrame(height,
    3358             :                                                 literal_array->GetIsolate());
    3359             :     }
    3360             : 
    3361             :     case Translation::BEGIN:
    3362             :     case Translation::DUPLICATED_OBJECT:
    3363             :     case Translation::ARGUMENTS_OBJECT:
    3364             :     case Translation::ARGUMENTS_ELEMENTS:
    3365             :     case Translation::ARGUMENTS_LENGTH:
    3366             :     case Translation::CAPTURED_OBJECT:
    3367             :     case Translation::REGISTER:
    3368             :     case Translation::INT32_REGISTER:
    3369             :     case Translation::UINT32_REGISTER:
    3370             :     case Translation::BOOL_REGISTER:
    3371             :     case Translation::FLOAT_REGISTER:
    3372             :     case Translation::DOUBLE_REGISTER:
    3373             :     case Translation::STACK_SLOT:
    3374             :     case Translation::INT32_STACK_SLOT:
    3375             :     case Translation::UINT32_STACK_SLOT:
    3376             :     case Translation::BOOL_STACK_SLOT:
    3377             :     case Translation::FLOAT_STACK_SLOT:
    3378             :     case Translation::DOUBLE_STACK_SLOT:
    3379             :     case Translation::LITERAL:
    3380             :       break;
    3381             :   }
    3382           0 :   FATAL("We should never get here - unexpected deopt info.");
    3383             :   return TranslatedFrame::InvalidFrame();
    3384             : }
    3385             : 
    3386             : 
    3387             : // static
    3388     1880631 : void TranslatedFrame::AdvanceIterator(
    3389     1889418 :     std::deque<TranslatedValue>::iterator* iter) {
    3390             :   int values_to_skip = 1;
    3391     5650680 :   while (values_to_skip > 0) {
    3392             :     // Consume the current element.
    3393     1889418 :     values_to_skip--;
    3394             :     // Add all the children.
    3395     1889418 :     values_to_skip += (*iter)->GetChildrenCount();
    3396             : 
    3397     1889418 :     (*iter)++;
    3398             :   }
    3399     1880631 : }
    3400             : 
    3401         658 : Address TranslatedState::ComputeArgumentsPosition(Address input_frame_pointer,
    3402             :                                                   bool is_rest, int* length) {
    3403             :   Address parent_frame_pointer = *reinterpret_cast<Address*>(
    3404         658 :       input_frame_pointer + StandardFrameConstants::kCallerFPOffset);
    3405             :   intptr_t parent_frame_type = Memory::intptr_at(
    3406         658 :       parent_frame_pointer + CommonFrameConstants::kContextOrFrameTypeOffset);
    3407             : 
    3408             :   Address arguments_frame;
    3409         658 :   if (parent_frame_type ==
    3410             :       StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)) {
    3411         532 :     if (length)
    3412             :       *length = Smi::cast(*reinterpret_cast<Object**>(
    3413             :                               parent_frame_pointer +
    3414             :                               ArgumentsAdaptorFrameConstants::kLengthOffset))
    3415        1064 :                     ->value();
    3416             :     arguments_frame = parent_frame_pointer;
    3417             :   } else {
    3418         126 :     if (length) *length = formal_parameter_count_;
    3419             :     arguments_frame = input_frame_pointer;
    3420             :   }
    3421             : 
    3422         658 :   if (is_rest) {
    3423             :     // If the actual number of arguments is less than the number of formal
    3424             :     // parameters, we have zero rest parameters.
    3425         104 :     if (length) *length = std::max(0, *length - formal_parameter_count_);
    3426             :   }
    3427             : 
    3428         658 :   return arguments_frame;
    3429             : }
    3430             : 
    3431             : // Creates translated values for an arguments backing store, or the backing
    3432             : // store for the rest parameters if {is_rest} is true. The TranslatedValue
    3433             : // objects for the fields are not read from the TranslationIterator, but instead
    3434             : // created on-the-fly based on dynamic information in the optimized frame.
    3435         329 : void TranslatedState::CreateArgumentsElementsTranslatedValues(
    3436             :     int frame_index, Address input_frame_pointer, bool is_rest,
    3437             :     FILE* trace_file) {
    3438         329 :   TranslatedFrame& frame = frames_[frame_index];
    3439             : 
    3440             :   int length;
    3441             :   Address arguments_frame =
    3442         329 :       ComputeArgumentsPosition(input_frame_pointer, is_rest, &length);
    3443             : 
    3444         329 :   int object_index = static_cast<int>(object_positions_.size());
    3445         329 :   int value_index = static_cast<int>(frame.values_.size());
    3446         329 :   if (trace_file != nullptr) {
    3447             :     PrintF(trace_file,
    3448             :            "arguments elements object #%d (is_rest = %d, length = %d)",
    3449           0 :            object_index, is_rest, length);
    3450             :   }
    3451         658 :   object_positions_.push_back({frame_index, value_index});
    3452             :   frame.Add(TranslatedValue::NewDeferredObject(
    3453         658 :       this, length + FixedArray::kHeaderSize / kPointerSize, object_index));
    3454             : 
    3455             :   frame.Add(
    3456         658 :       TranslatedValue::NewTagged(this, isolate_->heap()->fixed_array_map()));
    3457         658 :   frame.Add(TranslatedValue::NewInt32(this, length));
    3458             : 
    3459        1481 :   for (int i = length - 1; i >= 0; --i) {
    3460             :     Address argument_slot = arguments_frame +
    3461             :                             CommonFrameConstants::kFixedFrameSizeAboveFp +
    3462        1152 :                             i * kPointerSize;
    3463             :     frame.Add(TranslatedValue::NewTagged(
    3464        2304 :         this, *reinterpret_cast<Object**>(argument_slot)));
    3465             :   }
    3466         329 : }
    3467             : 
    3468             : // We can't intermix stack decoding and allocations because the deoptimization
    3469             : // infrastracture is not GC safe.
    3470             : // Thus we build a temporary structure in malloced space.
    3471             : // The TranslatedValue objects created correspond to the static translation
    3472             : // instructions from the TranslationIterator, except for
    3473             : // Translation::ARGUMENTS_ELEMENTS, where the number and values of the
    3474             : // FixedArray elements depend on dynamic information from the optimized frame.
    3475             : // Returns the number of expected nested translations from the
    3476             : // TranslationIterator.
    3477     2749033 : int TranslatedState::CreateNextTranslatedValue(
    3478             :     int frame_index, TranslationIterator* iterator, FixedArray* literal_array,
    3479             :     Address fp, RegisterValues* registers, FILE* trace_file) {
    3480             :   disasm::NameConverter converter;
    3481             : 
    3482     2749033 :   TranslatedFrame& frame = frames_[frame_index];
    3483     2749033 :   int value_index = static_cast<int>(frame.values_.size());
    3484             : 
    3485             :   Translation::Opcode opcode =
    3486     2749033 :       static_cast<Translation::Opcode>(iterator->Next());
    3487     2749033 :   switch (opcode) {
    3488             :     case Translation::BEGIN:
    3489             :     case Translation::JS_FRAME:
    3490             :     case Translation::INTERPRETED_FRAME:
    3491             :     case Translation::ARGUMENTS_ADAPTOR_FRAME:
    3492             :     case Translation::TAIL_CALLER_FRAME:
    3493             :     case Translation::CONSTRUCT_STUB_FRAME:
    3494             :     case Translation::GETTER_STUB_FRAME:
    3495             :     case Translation::SETTER_STUB_FRAME:
    3496             :     case Translation::COMPILED_STUB_FRAME:
    3497             :       // Peeled off before getting here.
    3498             :       break;
    3499             : 
    3500             :     case Translation::DUPLICATED_OBJECT: {
    3501       27789 :       int object_id = iterator->Next();
    3502       27789 :       if (trace_file != nullptr) {
    3503           0 :         PrintF(trace_file, "duplicated object #%d", object_id);
    3504             :       }
    3505       27789 :       object_positions_.push_back(object_positions_[object_id]);
    3506             :       TranslatedValue translated_value =
    3507             :           TranslatedValue::NewDuplicateObject(this, object_id);
    3508             :       frame.Add(translated_value);
    3509             :       return translated_value.GetChildrenCount();
    3510             :     }
    3511             : 
    3512             :     case Translation::ARGUMENTS_OBJECT: {
    3513         757 :       int arg_count = iterator->Next();
    3514         757 :       int object_index = static_cast<int>(object_positions_.size());
    3515         757 :       if (trace_file != nullptr) {
    3516             :         PrintF(trace_file, "arguments object #%d (length = %d)", object_index,
    3517           0 :                arg_count);
    3518             :       }
    3519        1514 :       object_positions_.push_back({frame_index, value_index});
    3520             :       TranslatedValue translated_value =
    3521             :           TranslatedValue::NewArgumentsObject(this, arg_count, object_index);
    3522             :       frame.Add(translated_value);
    3523             :       return translated_value.GetChildrenCount();
    3524             :     }
    3525             : 
    3526             :     case Translation::ARGUMENTS_ELEMENTS: {
    3527         329 :       bool is_rest = iterator->Next();
    3528             :       CreateArgumentsElementsTranslatedValues(frame_index, fp, is_rest,
    3529         329 :                                               trace_file);
    3530         329 :       return 0;
    3531             :     }
    3532             : 
    3533             :     case Translation::ARGUMENTS_LENGTH: {
    3534         329 :       bool is_rest = iterator->Next();
    3535             :       int length;
    3536         329 :       ComputeArgumentsPosition(fp, is_rest, &length);
    3537         329 :       if (trace_file != nullptr) {
    3538             :         PrintF(trace_file, "arguments length field (is_rest = %d, length = %d)",
    3539           0 :                is_rest, length);
    3540             :       }
    3541         658 :       frame.Add(TranslatedValue::NewInt32(this, length));
    3542             :       return 0;
    3543             :     }
    3544             : 
    3545             :     case Translation::CAPTURED_OBJECT: {
    3546       15278 :       int field_count = iterator->Next();
    3547       15278 :       int object_index = static_cast<int>(object_positions_.size());
    3548       15278 :       if (trace_file != nullptr) {
    3549             :         PrintF(trace_file, "captured object #%d (length = %d)", object_index,
    3550           0 :                field_count);
    3551             :       }
    3552       30556 :       object_positions_.push_back({frame_index, value_index});
    3553             :       TranslatedValue translated_value =
    3554             :           TranslatedValue::NewDeferredObject(this, field_count, object_index);
    3555             :       frame.Add(translated_value);
    3556             :       return translated_value.GetChildrenCount();
    3557             :     }
    3558             : 
    3559             :     case Translation::REGISTER: {
    3560      215563 :       int input_reg = iterator->Next();
    3561      215563 :       if (registers == nullptr) {
    3562             :         TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
    3563             :         frame.Add(translated_value);
    3564             :         return translated_value.GetChildrenCount();
    3565             :       }
    3566      193259 :       intptr_t value = registers->GetRegister(input_reg);
    3567      193259 :       if (trace_file != nullptr) {
    3568             :         PrintF(trace_file, "0x%08" V8PRIxPTR " ; %s ", value,
    3569           0 :                converter.NameOfCPURegister(input_reg));
    3570           0 :         reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
    3571             :       }
    3572             :       TranslatedValue translated_value =
    3573      193259 :           TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
    3574             :       frame.Add(translated_value);
    3575             :       return translated_value.GetChildrenCount();
    3576             :     }
    3577             : 
    3578             :     case Translation::INT32_REGISTER: {
    3579        3912 :       int input_reg = iterator->Next();
    3580        3912 :       if (registers == nullptr) {
    3581             :         TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
    3582             :         frame.Add(translated_value);
    3583             :         return translated_value.GetChildrenCount();
    3584             :       }
    3585        1472 :       intptr_t value = registers->GetRegister(input_reg);
    3586        1472 :       if (trace_file != nullptr) {
    3587             :         PrintF(trace_file, "%" V8PRIdPTR " ; %s ", value,
    3588           0 :                converter.NameOfCPURegister(input_reg));
    3589             :       }
    3590             :       TranslatedValue translated_value =
    3591        1472 :           TranslatedValue::NewInt32(this, static_cast<int32_t>(value));
    3592             :       frame.Add(translated_value);
    3593             :       return translated_value.GetChildrenCount();
    3594             :     }
    3595             : 
    3596             :     case Translation::UINT32_REGISTER: {
    3597          24 :       int input_reg = iterator->Next();
    3598          24 :       if (registers == nullptr) {
    3599             :         TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
    3600             :         frame.Add(translated_value);
    3601             :         return translated_value.GetChildrenCount();
    3602             :       }
    3603          24 :       intptr_t value = registers->GetRegister(input_reg);
    3604          24 :       if (trace_file != nullptr) {
    3605             :         PrintF(trace_file, "%" V8PRIuPTR " ; %s (uint)", value,
    3606           0 :                converter.NameOfCPURegister(input_reg));
    3607           0 :         reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
    3608             :       }
    3609             :       TranslatedValue translated_value =
    3610          24 :           TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value));
    3611             :       frame.Add(translated_value);
    3612             :       return translated_value.GetChildrenCount();
    3613             :     }
    3614             : 
    3615             :     case Translation::BOOL_REGISTER: {
    3616          58 :       int input_reg = iterator->Next();
    3617          58 :       if (registers == nullptr) {
    3618             :         TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
    3619             :         frame.Add(translated_value);
    3620             :         return translated_value.GetChildrenCount();
    3621             :       }
    3622          58 :       intptr_t value = registers->GetRegister(input_reg);
    3623          58 :       if (trace_file != nullptr) {
    3624             :         PrintF(trace_file, "%" V8PRIdPTR " ; %s (bool)", value,
    3625           0 :                converter.NameOfCPURegister(input_reg));
    3626             :       }
    3627             :       TranslatedValue translated_value =
    3628          58 :           TranslatedValue::NewBool(this, static_cast<uint32_t>(value));
    3629             :       frame.Add(translated_value);
    3630             :       return translated_value.GetChildrenCount();
    3631             :     }
    3632             : 
    3633             :     case Translation::FLOAT_REGISTER: {
    3634          91 :       int input_reg = iterator->Next();
    3635          91 :       if (registers == nullptr) {
    3636             :         TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
    3637             :         frame.Add(translated_value);
    3638             :         return translated_value.GetChildrenCount();
    3639             :       }
    3640         182 :       Float32 value = registers->GetFloatRegister(input_reg);
    3641          91 :       if (trace_file != nullptr) {
    3642             :         PrintF(trace_file, "%e ; %s (float)", value.get_scalar(),
    3643             :                RegisterConfiguration::Crankshaft()->GetFloatRegisterName(
    3644           0 :                    input_reg));
    3645             :       }
    3646             :       TranslatedValue translated_value = TranslatedValue::NewFloat(this, value);
    3647             :       frame.Add(translated_value);
    3648             :       return translated_value.GetChildrenCount();
    3649             :     }
    3650             : 
    3651             :     case Translation::DOUBLE_REGISTER: {
    3652         800 :       int input_reg = iterator->Next();
    3653         800 :       if (registers == nullptr) {
    3654             :         TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
    3655             :         frame.Add(translated_value);
    3656             :         return translated_value.GetChildrenCount();
    3657             :       }
    3658        1600 :       Float64 value = registers->GetDoubleRegister(input_reg);
    3659         800 :       if (trace_file != nullptr) {
    3660             :         PrintF(trace_file, "%e ; %s (double)", value.get_scalar(),
    3661             :                RegisterConfiguration::Crankshaft()->GetDoubleRegisterName(
    3662           0 :                    input_reg));
    3663             :       }
    3664             :       TranslatedValue translated_value =
    3665             :           TranslatedValue::NewDouble(this, value);
    3666             :       frame.Add(translated_value);
    3667             :       return translated_value.GetChildrenCount();
    3668             :     }
    3669             : 
    3670             :     case Translation::STACK_SLOT: {
    3671             :       int slot_offset =
    3672      943949 :           OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
    3673      943949 :       intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset));
    3674      943949 :       if (trace_file != nullptr) {
    3675             :         PrintF(trace_file, "0x%08" V8PRIxPTR " ; [fp %c %d] ", value,
    3676           0 :                slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
    3677           0 :         reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
    3678             :       }
    3679             :       TranslatedValue translated_value =
    3680      943949 :           TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
    3681             :       frame.Add(translated_value);
    3682             :       return translated_value.GetChildrenCount();
    3683             :     }
    3684             : 
    3685             :     case Translation::INT32_STACK_SLOT: {
    3686             :       int slot_offset =
    3687      138120 :           OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
    3688             :       uint32_t value = GetUInt32Slot(fp, slot_offset);
    3689      138120 :       if (trace_file != nullptr) {
    3690             :         PrintF(trace_file, "%d ; (int) [fp %c %d] ",
    3691             :                static_cast<int32_t>(value), slot_offset < 0 ? '-' : '+',
    3692           0 :                std::abs(slot_offset));
    3693             :       }
    3694      138120 :       TranslatedValue translated_value = TranslatedValue::NewInt32(this, value);
    3695             :       frame.Add(translated_value);
    3696             :       return translated_value.GetChildrenCount();
    3697             :     }
    3698             : 
    3699             :     case Translation::UINT32_STACK_SLOT: {
    3700             :       int slot_offset =
    3701           9 :           OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
    3702             :       uint32_t value = GetUInt32Slot(fp, slot_offset);
    3703           9 :       if (trace_file != nullptr) {
    3704             :         PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value,
    3705           0 :                slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
    3706             :       }
    3707             :       TranslatedValue translated_value =
    3708             :           TranslatedValue::NewUInt32(this, value);
    3709             :       frame.Add(translated_value);
    3710             :       return translated_value.GetChildrenCount();
    3711             :     }
    3712             : 
    3713             :     case Translation::BOOL_STACK_SLOT: {
    3714             :       int slot_offset =
    3715          10 :           OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
    3716             :       uint32_t value = GetUInt32Slot(fp, slot_offset);
    3717          10 :       if (trace_file != nullptr) {
    3718             :         PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value,
    3719           0 :                slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
    3720             :       }
    3721             :       TranslatedValue translated_value = TranslatedValue::NewBool(this, value);
    3722             :       frame.Add(translated_value);
    3723             :       return translated_value.GetChildrenCount();
    3724             :     }
    3725             : 
    3726             :     case Translation::FLOAT_STACK_SLOT: {
    3727             :       int slot_offset =
    3728         189 :           OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
    3729         189 :       Float32 value = GetFloatSlot(fp, slot_offset);
    3730         189 :       if (trace_file != nullptr) {
    3731             :         PrintF(trace_file, "%e ; (float) [fp %c %d] ", value.get_scalar(),
    3732           0 :                slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
    3733             :       }
    3734             :       TranslatedValue translated_value = TranslatedValue::NewFloat(this, value);
    3735             :       frame.Add(translated_value);
    3736             :       return translated_value.GetChildrenCount();
    3737             :     }
    3738             : 
    3739             :     case Translation::DOUBLE_STACK_SLOT: {
    3740             :       int slot_offset =
    3741      142257 :           OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
    3742      142257 :       Float64 value = GetDoubleSlot(fp, slot_offset);
    3743      142257 :       if (trace_file != nullptr) {
    3744             :         PrintF(trace_file, "%e ; (double) [fp %c %d] ", value.get_scalar(),
    3745           0 :                slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
    3746             :       }
    3747             :       TranslatedValue translated_value =
    3748             :           TranslatedValue::NewDouble(this, value);
    3749             :       frame.Add(translated_value);
    3750             :       return translated_value.GetChildrenCount();
    3751             :     }
    3752             : 
    3753             :     case Translation::LITERAL: {
    3754     1259569 :       int literal_index = iterator->Next();
    3755             :       Object* value = literal_array->get(literal_index);
    3756     1259569 :       if (trace_file != nullptr) {
    3757             :         PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ",
    3758           0 :                reinterpret_cast<intptr_t>(value), literal_index);
    3759           0 :         reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
    3760             :       }
    3761             : 
    3762             :       TranslatedValue translated_value =
    3763             :           TranslatedValue::NewTagged(this, value);
    3764             :       frame.Add(translated_value);
    3765             :       return translated_value.GetChildrenCount();
    3766             :     }
    3767             :   }
    3768             : 
    3769           0 :   FATAL("We should never get here - unexpected deopt info.");
    3770             :   TranslatedValue translated_value =
    3771             :       TranslatedValue(nullptr, TranslatedValue::kInvalid);
    3772             :   frame.Add(translated_value);
    3773             :   return translated_value.GetChildrenCount();
    3774             : }
    3775             : 
    3776             : 
    3777       62591 : TranslatedState::TranslatedState(JavaScriptFrame* frame)
    3778             :     : isolate_(nullptr),
    3779             :       stack_frame_pointer_(nullptr),
    3780       62591 :       has_adapted_arguments_(false) {
    3781       62591 :   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    3782             :   DeoptimizationInputData* data =
    3783       62591 :       static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
    3784             :   DCHECK(data != nullptr && deopt_index != Safepoint::kNoDeoptimizationIndex);
    3785             :   TranslationIterator it(data->TranslationByteArray(),
    3786       62591 :                          data->TranslationIndex(deopt_index)->value());
    3787             :   Init(frame->fp(), &it, data->LiteralArray(), nullptr /* registers */,
    3788             :        nullptr /* trace file */,
    3789      125182 :        frame->function()->shared()->internal_formal_parameter_count());
    3790       62591 : }
    3791             : 
    3792             : 
    3793           0 : TranslatedState::TranslatedState()
    3794             :     : isolate_(nullptr),
    3795             :       stack_frame_pointer_(nullptr),
    3796      151227 :       has_adapted_arguments_(false) {}
    3797             : 
    3798      213818 : void TranslatedState::Init(Address input_frame_pointer,
    3799      213818 :                            TranslationIterator* iterator,
    3800             :                            FixedArray* literal_array, RegisterValues* registers,
    3801             :                            FILE* trace_file, int formal_parameter_count) {
    3802             :   DCHECK(frames_.empty());
    3803             : 
    3804      213818 :   formal_parameter_count_ = formal_parameter_count;
    3805             : 
    3806      213818 :   isolate_ = literal_array->GetIsolate();
    3807             :   // Read out the 'header' translation.
    3808             :   Translation::Opcode opcode =
    3809      213818 :       static_cast<Translation::Opcode>(iterator->Next());
    3810      213818 :   CHECK(opcode == Translation::BEGIN);
    3811             : 
    3812      213818 :   int count = iterator->Next();
    3813      213818 :   iterator->Next();  // Drop JS frames count.
    3814             : 
    3815      213818 :   frames_.reserve(count);
    3816             : 
    3817      213818 :   std::stack<int> nested_counts;
    3818             : 
    3819             :   // Read the frames
    3820      549722 :   for (int frame_index = 0; frame_index < count; frame_index++) {
    3821             :     // Read the frame descriptor.
    3822             :     frames_.push_back(CreateNextTranslatedFrame(
    3823      671808 :         iterator, literal_array, input_frame_pointer, trace_file));
    3824      335904 :     TranslatedFrame& frame = frames_.back();
    3825             : 
    3826             :     // Read the values.
    3827      335904 :     int values_to_process = frame.GetValueCount();
    3828     3756745 :     while (values_to_process > 0 || !nested_counts.empty()) {
    3829     2749033 :       if (trace_file != nullptr) {
    3830           0 :         if (nested_counts.empty()) {
    3831             :           // For top level values, print the value number.
    3832             :           PrintF(trace_file, "    %3i: ",
    3833           0 :                  frame.GetValueCount() - values_to_process);
    3834             :         } else {
    3835             :           // Take care of indenting for nested values.
    3836           0 :           PrintF(trace_file, "         ");
    3837           0 :           for (size_t j = 0; j < nested_counts.size(); j++) {
    3838           0 :             PrintF(trace_file, "  ");
    3839             :           }
    3840             :         }
    3841             :       }
    3842             : 
    3843             :       int nested_count =
    3844             :           CreateNextTranslatedValue(frame_index, iterator, literal_array,
    3845     2749033 :                                     input_frame_pointer, registers, trace_file);
    3846             : 
    3847     2749033 :       if (trace_file != nullptr) {
    3848           0 :         PrintF(trace_file, "\n");
    3849             :       }
    3850             : 
    3851             :       // Update the value count and resolve the nesting.
    3852     2749033 :       values_to_process--;
    3853     2749033 :       if (nested_count > 0) {
    3854             :         nested_counts.push(values_to_process);
    3855       15968 :         values_to_process = nested_count;
    3856             :       } else {
    3857     3100905 :         while (values_to_process == 0 && !nested_counts.empty()) {
    3858       15968 :           values_to_process = nested_counts.top();
    3859             :           nested_counts.pop();
    3860             :         }
    3861             :       }
    3862             :     }
    3863             :   }
    3864             : 
    3865      213818 :   CHECK(!iterator->HasNext() ||
    3866             :         static_cast<Translation::Opcode>(iterator->Next()) ==
    3867             :             Translation::BEGIN);
    3868      213818 : }
    3869             : 
    3870             : 
    3871      187171 : void TranslatedState::Prepare(bool has_adapted_arguments,
    3872             :                               Address stack_frame_pointer) {
    3873      683599 :   for (auto& frame : frames_) frame.Handlify();
    3874             : 
    3875      187171 :   stack_frame_pointer_ = stack_frame_pointer;
    3876      187171 :   has_adapted_arguments_ = has_adapted_arguments;
    3877             : 
    3878      187171 :   UpdateFromPreviouslyMaterializedObjects();
    3879      187171 : }
    3880             : 
    3881             : class TranslatedState::CapturedObjectMaterializer {
    3882             :  public:
    3883             :   CapturedObjectMaterializer(TranslatedState* state, int frame_index,
    3884             :                              int field_count)
    3885        2030 :       : state_(state), frame_index_(frame_index), field_count_(field_count) {}
    3886             : 
    3887        9661 :   Handle<Object> FieldAt(int* value_index) {
    3888        9661 :     CHECK(field_count_ > 0);
    3889        9661 :     --field_count_;
    3890        9661 :     return state_->MaterializeAt(frame_index_, value_index);
    3891             :   }
    3892             : 
    3893        2030 :   ~CapturedObjectMaterializer() { CHECK_EQ(0, field_count_); }
    3894             : 
    3895             :  private:
    3896             :   TranslatedState* state_;
    3897             :   int frame_index_;
    3898             :   int field_count_;
    3899             : };
    3900             : 
    3901        2030 : Handle<Object> TranslatedState::MaterializeCapturedObjectAt(
    3902             :     TranslatedValue* slot, int frame_index, int* value_index) {
    3903             :   int length = slot->GetChildrenCount();
    3904             : 
    3905             :   CapturedObjectMaterializer materializer(this, frame_index, length);
    3906             : 
    3907             :   Handle<Object> result;
    3908        2030 :   if (slot->value_.ToHandle(&result)) {
    3909             :     // This has been previously materialized, return the previous value.
    3910             :     // We still need to skip all the nested objects.
    3911        1746 :     for (int i = 0; i < length; i++) {
    3912        1746 :       materializer.FieldAt(value_index);
    3913             :     }
    3914             : 
    3915         330 :     return result;
    3916             :   }
    3917             : 
    3918        1700 :   Handle<Object> map_object = materializer.FieldAt(value_index);
    3919        1700 :   Handle<Map> map = Map::GeneralizeAllFields(Handle<Map>::cast(map_object));
    3920        1700 :   switch (map->instance_type()) {
    3921             :     case MUTABLE_HEAP_NUMBER_TYPE:
    3922             :     case HEAP_NUMBER_TYPE: {
    3923             :       // Reuse the HeapNumber value directly as it is already properly
    3924             :       // tagged and skip materializing the HeapNumber explicitly.
    3925           0 :       Handle<Object> object = materializer.FieldAt(value_index);
    3926           0 :       slot->value_ = object;
    3927             :       // On 32-bit architectures, there is an extra slot there because
    3928             :       // the escape analysis calculates the number of slots as
    3929             :       // object-size/pointer-size. To account for this, we read out
    3930             :       // any extra slots.
    3931           0 :       for (int i = 0; i < length - 2; i++) {
    3932           0 :         materializer.FieldAt(value_index);
    3933             :       }
    3934           0 :       return object;
    3935             :     }
    3936             :     case JS_OBJECT_TYPE:
    3937             :     case JS_ERROR_TYPE:
    3938             :     case JS_ARGUMENTS_TYPE: {
    3939             :       Handle<JSObject> object =
    3940         982 :           isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED);
    3941         982 :       slot->value_ = object;
    3942         982 :       Handle<Object> properties = materializer.FieldAt(value_index);
    3943         982 :       Handle<Object> elements = materializer.FieldAt(value_index);
    3944         982 :       object->set_properties(FixedArray::cast(*properties));
    3945         982 :       object->set_elements(FixedArrayBase::cast(*elements));
    3946        2409 :       for (int i = 0; i < length - 3; ++i) {
    3947        1427 :         Handle<Object> value = materializer.FieldAt(value_index);
    3948        1427 :         FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i);
    3949        1427 :         object->FastPropertyAtPut(index, *value);
    3950             :       }
    3951         982 :       return object;
    3952             :     }
    3953             :     case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
    3954             :     case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
    3955             :     case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
    3956             :     case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3957             :     case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3958             :     case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3959             :     case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3960             :     case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3961             :     case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3962             :     case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3963             :     case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3964             :     case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3965             :     case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3966             :     case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3967             :     case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3968             :     case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3969             :     case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3970             :     case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3971             :     case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    3972             :     case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
    3973             :     case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
    3974             :     case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
    3975             :     case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
    3976             :     case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
    3977             :     case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
    3978             :     case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
    3979             :     case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
    3980             :     case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
    3981             :     case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    3982             :     case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    3983             :     case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
    3984             :     case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
    3985             :     case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    3986             :     case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    3987             :     case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE: {
    3988             :       Handle<JSArrayIterator> object = Handle<JSArrayIterator>::cast(
    3989          15 :           isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
    3990          15 :       slot->value_ = object;
    3991             :       // Initialize the index to zero to make the heap verifier happy.
    3992          15 :       object->set_index(Smi::FromInt(0));
    3993          15 :       Handle<Object> properties = materializer.FieldAt(value_index);
    3994          15 :       Handle<Object> elements = materializer.FieldAt(value_index);
    3995          15 :       Handle<Object> iterated_object = materializer.FieldAt(value_index);
    3996          15 :       Handle<Object> next_index = materializer.FieldAt(value_index);
    3997          15 :       Handle<Object> iterated_object_map = materializer.FieldAt(value_index);
    3998          15 :       object->set_properties(FixedArray::cast(*properties));
    3999          15 :       object->set_elements(FixedArrayBase::cast(*elements));
    4000          15 :       object->set_object(*iterated_object);
    4001          15 :       object->set_index(*next_index);
    4002          15 :       object->set_object_map(*iterated_object_map);
    4003          15 :       return object;
    4004             :     }
    4005             :     case JS_STRING_ITERATOR_TYPE: {
    4006             :       Handle<JSStringIterator> object = Handle<JSStringIterator>::cast(
    4007           8 :           isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
    4008           8 :       slot->value_ = object;
    4009             :       // Initialize the index to zero to make the heap verifier happy.
    4010             :       object->set_index(0);
    4011           8 :       Handle<Object> properties = materializer.FieldAt(value_index);
    4012           8 :       Handle<Object> elements = materializer.FieldAt(value_index);
    4013           8 :       Handle<Object> iterated_string = materializer.FieldAt(value_index);
    4014           8 :       Handle<Object> next_index = materializer.FieldAt(value_index);
    4015           8 :       object->set_properties(FixedArray::cast(*properties));
    4016           8 :       object->set_elements(FixedArrayBase::cast(*elements));
    4017           8 :       CHECK(iterated_string->IsString());
    4018           8 :       object->set_string(String::cast(*iterated_string));
    4019           8 :       CHECK(next_index->IsSmi());
    4020             :       object->set_index(Smi::cast(*next_index)->value());
    4021           8 :       return object;
    4022             :     }
    4023             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE: {
    4024             :       Handle<JSAsyncFromSyncIterator> object =
    4025             :           Handle<JSAsyncFromSyncIterator>::cast(
    4026           0 :               isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
    4027           0 :       slot->value_ = object;
    4028           0 :       Handle<Object> properties = materializer.FieldAt(value_index);
    4029           0 :       Handle<Object> elements = materializer.FieldAt(value_index);
    4030           0 :       Handle<Object> sync_iterator = materializer.FieldAt(value_index);
    4031           0 :       object->set_properties(FixedArray::cast(*properties));
    4032           0 :       object->set_elements(FixedArrayBase::cast(*elements));
    4033           0 :       object->set_sync_iterator(JSReceiver::cast(*sync_iterator));
    4034           0 :       return object;
    4035             :     }
    4036             :     case JS_ARRAY_TYPE: {
    4037             :       Handle<JSArray> object = Handle<JSArray>::cast(
    4038         157 :           isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
    4039         157 :       slot->value_ = object;
    4040         157 :       Handle<Object> properties = materializer.FieldAt(value_index);
    4041         157 :       Handle<Object> elements = materializer.FieldAt(value_index);
    4042         157 :       Handle<Object> length = materializer.FieldAt(value_index);
    4043         157 :       object->set_properties(FixedArray::cast(*properties));
    4044         157 :       object->set_elements(FixedArrayBase::cast(*elements));
    4045         157 :       object->set_length(*length);
    4046         157 :       return object;
    4047             :     }
    4048             :     case JS_FUNCTION_TYPE: {
    4049             :       Handle<SharedFunctionInfo> temporary_shared =
    4050             :           isolate_->factory()->NewSharedFunctionInfo(
    4051           0 :               isolate_->factory()->empty_string(), MaybeHandle<Code>(), false);
    4052             :       Handle<JSFunction> object =
    4053             :           isolate_->factory()->NewFunctionFromSharedFunctionInfo(
    4054             :               map, temporary_shared, isolate_->factory()->undefined_value(),
    4055           0 :               NOT_TENURED);
    4056           0 :       slot->value_ = object;
    4057           0 :       Handle<Object> properties = materializer.FieldAt(value_index);
    4058           0 :       Handle<Object> elements = materializer.FieldAt(value_index);
    4059           0 :       Handle<Object> prototype = materializer.FieldAt(value_index);
    4060           0 :       Handle<Object> shared = materializer.FieldAt(value_index);
    4061           0 :       Handle<Object> context = materializer.FieldAt(value_index);
    4062           0 :       Handle<Object> vector_cell = materializer.FieldAt(value_index);
    4063           0 :       Handle<Object> entry = materializer.FieldAt(value_index);
    4064           0 :       Handle<Object> next_link = materializer.FieldAt(value_index);
    4065           0 :       object->ReplaceCode(*isolate_->builtins()->CompileLazy());
    4066           0 :       object->set_map(*map);
    4067           0 :       object->set_properties(FixedArray::cast(*properties));
    4068           0 :       object->set_elements(FixedArrayBase::cast(*elements));
    4069           0 :       object->set_prototype_or_initial_map(*prototype);
    4070           0 :       object->set_shared(SharedFunctionInfo::cast(*shared));
    4071           0 :       object->set_context(Context::cast(*context));
    4072           0 :       object->set_feedback_vector_cell(Cell::cast(*vector_cell));
    4073           0 :       CHECK(entry->IsNumber());  // Entry to compile lazy stub.
    4074           0 :       CHECK(next_link->IsUndefined(isolate_));
    4075           0 :       return object;
    4076             :     }
    4077             :     case CONS_STRING_TYPE: {
    4078             :       Handle<ConsString> object = Handle<ConsString>::cast(
    4079             :           isolate_->factory()
    4080             :               ->NewConsString(isolate_->factory()->undefined_string(),
    4081             :                               isolate_->factory()->undefined_string())
    4082          96 :               .ToHandleChecked());
    4083          32 :       slot->value_ = object;
    4084          32 :       Handle<Object> hash = materializer.FieldAt(value_index);
    4085          32 :       Handle<Object> length = materializer.FieldAt(value_index);
    4086          32 :       Handle<Object> first = materializer.FieldAt(value_index);
    4087          32 :       Handle<Object> second = materializer.FieldAt(value_index);
    4088          32 :       object->set_map(*map);
    4089             :       object->set_length(Smi::cast(*length)->value());
    4090          32 :       object->set_first(String::cast(*first));
    4091          32 :       object->set_second(String::cast(*second));
    4092          32 :       CHECK(hash->IsNumber());  // The {Name::kEmptyHashField} value.
    4093          32 :       return object;
    4094             :     }
    4095             :     case CONTEXT_EXTENSION_TYPE: {
    4096             :       Handle<ContextExtension> object =
    4097             :           isolate_->factory()->NewContextExtension(
    4098             :               isolate_->factory()->NewScopeInfo(1),
    4099          56 :               isolate_->factory()->undefined_value());
    4100          28 :       slot->value_ = object;
    4101          28 :       Handle<Object> scope_info = materializer.FieldAt(value_index);
    4102          28 :       Handle<Object> extension = materializer.FieldAt(value_index);
    4103          28 :       object->set_scope_info(ScopeInfo::cast(*scope_info));
    4104          28 :       object->set_extension(*extension);
    4105          28 :       return object;
    4106             :     }
    4107             :     case FIXED_ARRAY_TYPE: {
    4108         461 :       Handle<Object> lengthObject = materializer.FieldAt(value_index);
    4109         461 :       int32_t length = 0;
    4110         461 :       CHECK(lengthObject->ToInt32(&length));
    4111         461 :       Handle<FixedArray> object = isolate_->factory()->NewFixedArray(length);
    4112             :       // We need to set the map, because the fixed array we are
    4113             :       // materializing could be a context or an arguments object,
    4114             :       // in which case we must retain that information.
    4115         461 :       object->set_map(*map);
    4116         461 :       slot->value_ = object;
    4117        1985 :       for (int i = 0; i < length; ++i) {
    4118        1524 :         Handle<Object> value = materializer.FieldAt(value_index);
    4119        1524 :         object->set(i, *value);
    4120             :       }
    4121         461 :       return object;
    4122             :     }
    4123             :     case FIXED_DOUBLE_ARRAY_TYPE: {
    4124             :       DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map());
    4125          17 :       Handle<Object> lengthObject = materializer.FieldAt(value_index);
    4126          17 :       int32_t length = 0;
    4127          17 :       CHECK(lengthObject->ToInt32(&length));
    4128             :       Handle<FixedArrayBase> object =
    4129          17 :           isolate_->factory()->NewFixedDoubleArray(length);
    4130          17 :       slot->value_ = object;
    4131          17 :       if (length > 0) {
    4132             :         Handle<FixedDoubleArray> double_array =
    4133             :             Handle<FixedDoubleArray>::cast(object);
    4134          60 :         for (int i = 0; i < length; ++i) {
    4135          60 :           Handle<Object> value = materializer.FieldAt(value_index);
    4136         120 :           if (value.is_identical_to(isolate_->factory()->the_hole_value())) {
    4137             :             double_array->set_the_hole(isolate_, i);
    4138             :           } else {
    4139          51 :             CHECK(value->IsNumber());
    4140             :             double_array->set(i, value->Number());
    4141             :           }
    4142             :         }
    4143             :       }
    4144          17 :       return object;
    4145             :     }
    4146             :     case STRING_TYPE:
    4147             :     case ONE_BYTE_STRING_TYPE:
    4148             :     case CONS_ONE_BYTE_STRING_TYPE:
    4149             :     case SLICED_STRING_TYPE:
    4150             :     case SLICED_ONE_BYTE_STRING_TYPE:
    4151             :     case EXTERNAL_STRING_TYPE:
    4152             :     case EXTERNAL_ONE_BYTE_STRING_TYPE:
    4153             :     case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
    4154             :     case SHORT_EXTERNAL_STRING_TYPE:
    4155             :     case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
    4156             :     case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
    4157             :     case THIN_STRING_TYPE:
    4158             :     case THIN_ONE_BYTE_STRING_TYPE:
    4159             :     case INTERNALIZED_STRING_TYPE:
    4160             :     case ONE_BYTE_INTERNALIZED_STRING_TYPE:
    4161             :     case EXTERNAL_INTERNALIZED_STRING_TYPE:
    4162             :     case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
    4163             :     case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
    4164             :     case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
    4165             :     case SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
    4166             :     case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
    4167             :     case SYMBOL_TYPE:
    4168             :     case ODDBALL_TYPE:
    4169             :     case JS_GLOBAL_OBJECT_TYPE:
    4170             :     case JS_GLOBAL_PROXY_TYPE:
    4171             :     case JS_API_OBJECT_TYPE:
    4172             :     case JS_SPECIAL_API_OBJECT_TYPE:
    4173             :     case JS_VALUE_TYPE:
    4174             :     case JS_MESSAGE_OBJECT_TYPE:
    4175             :     case JS_DATE_TYPE:
    4176             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    4177             :     case JS_GENERATOR_OBJECT_TYPE:
    4178             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
    4179             :     case JS_MODULE_NAMESPACE_TYPE:
    4180             :     case JS_ARRAY_BUFFER_TYPE:
    4181             :     case JS_REGEXP_TYPE:
    4182             :     case JS_TYPED_ARRAY_TYPE:
    4183             :     case JS_DATA_VIEW_TYPE:
    4184             :     case JS_SET_TYPE:
    4185             :     case JS_MAP_TYPE:
    4186             :     case JS_SET_ITERATOR_TYPE:
    4187             :     case JS_MAP_ITERATOR_TYPE:
    4188             :     case JS_WEAK_MAP_TYPE:
    4189             :     case JS_WEAK_SET_TYPE:
    4190             :     case JS_PROMISE_CAPABILITY_TYPE:
    4191             :     case JS_PROMISE_TYPE:
    4192             :     case JS_BOUND_FUNCTION_TYPE:
    4193             :     case JS_PROXY_TYPE:
    4194             :     case MAP_TYPE:
    4195             :     case ALLOCATION_SITE_TYPE:
    4196             :     case ACCESSOR_INFO_TYPE:
    4197             :     case SHARED_FUNCTION_INFO_TYPE:
    4198             :     case FUNCTION_TEMPLATE_INFO_TYPE:
    4199             :     case ACCESSOR_PAIR_TYPE:
    4200             :     case BYTE_ARRAY_TYPE:
    4201             :     case BYTECODE_ARRAY_TYPE:
    4202             :     case TRANSITION_ARRAY_TYPE:
    4203             :     case FOREIGN_TYPE:
    4204             :     case SCRIPT_TYPE:
    4205             :     case CODE_TYPE:
    4206             :     case PROPERTY_CELL_TYPE:
    4207             :     case MODULE_TYPE:
    4208             :     case MODULE_INFO_ENTRY_TYPE:
    4209             :     case FREE_SPACE_TYPE:
    4210             : #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
    4211             :   case FIXED_##TYPE##_ARRAY_TYPE:
    4212             :       TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
    4213             : #undef FIXED_TYPED_ARRAY_CASE
    4214             :     case FILLER_TYPE:
    4215             :     case ACCESS_CHECK_INFO_TYPE:
    4216             :     case INTERCEPTOR_INFO_TYPE:
    4217             :     case OBJECT_TEMPLATE_INFO_TYPE:
    4218             :     case ALLOCATION_MEMENTO_TYPE:
    4219             :     case ALIASED_ARGUMENTS_ENTRY_TYPE:
    4220             :     case PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE:
    4221             :     case PROMISE_REACTION_JOB_INFO_TYPE:
    4222             :     case DEBUG_INFO_TYPE:
    4223             :     case STACK_FRAME_INFO_TYPE:
    4224             :     case CELL_TYPE:
    4225             :     case WEAK_CELL_TYPE:
    4226             :     case PROTOTYPE_INFO_TYPE:
    4227             :     case TUPLE2_TYPE:
    4228             :     case TUPLE3_TYPE:
    4229             :     case ASYNC_GENERATOR_REQUEST_TYPE:
    4230             :     case PADDING_TYPE_1:
    4231             :     case PADDING_TYPE_2:
    4232             :     case PADDING_TYPE_3:
    4233             :     case PADDING_TYPE_4:
    4234           0 :       OFStream os(stderr);
    4235           0 :       os << "[couldn't handle instance type " << map->instance_type() << "]"
    4236             :          << std::endl;
    4237           0 :       UNREACHABLE();
    4238             :       break;
    4239             :   }
    4240           0 :   UNREACHABLE();
    4241        2030 :   return Handle<Object>::null();
    4242             : }
    4243             : 
    4244       11668 : Handle<Object> TranslatedState::MaterializeAt(int frame_index,
    4245           0 :                                               int* value_index) {
    4246       23336 :   CHECK_LT(static_cast<size_t>(frame_index), frames().size());
    4247          12 :   TranslatedFrame* frame = &(frames_[frame_index]);
    4248       11668 :   CHECK_LT(static_cast<size_t>(*value_index), frame->values_.size());
    4249             : 
    4250       11668 :   TranslatedValue* slot = &(frame->values_[*value_index]);
    4251       11668 :   (*value_index)++;
    4252             : 
    4253       11668 :   switch (slot->kind()) {
    4254             :     case TranslatedValue::kTagged:
    4255             :     case TranslatedValue::kInt32:
    4256             :     case TranslatedValue::kUInt32:
    4257             :     case TranslatedValue::kBoolBit:
    4258             :     case TranslatedValue::kFloat:
    4259             :     case TranslatedValue::kDouble: {
    4260        9406 :       slot->MaterializeSimple();
    4261        9406 :       Handle<Object> value = slot->GetValue();
    4262        9406 :       if (value->IsMutableHeapNumber()) {
    4263           0 :         HeapNumber::cast(*value)->set_map(isolate()->heap()->heap_number_map());
    4264             :       }
    4265        9406 :       return value;
    4266             :     }
    4267             : 
    4268             :     case TranslatedValue::kArgumentsObject: {
    4269             :       int length = slot->GetChildrenCount();
    4270             :       Handle<JSObject> arguments;
    4271         220 :       if (GetAdaptedArguments(&arguments, frame_index)) {
    4272             :         // Store the materialized object and consume the nested values.
    4273          35 :         for (int i = 0; i < length; ++i) {
    4274          35 :           MaterializeAt(frame_index, value_index);
    4275             :         }
    4276             :       } else {
    4277             :         Handle<JSFunction> function =
    4278         165 :             Handle<JSFunction>::cast(frame->front().GetValue());
    4279         165 :         arguments = isolate_->factory()->NewArgumentsObject(function, length);
    4280         165 :         Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
    4281             :         DCHECK_EQ(array->length(), length);
    4282         165 :         arguments->set_elements(*array);
    4283         457 :         for (int i = 0; i < length; ++i) {
    4284         292 :           Handle<Object> value = MaterializeAt(frame_index, value_index);
    4285         292 :           array->set(i, *value);
    4286             :         }
    4287             :       }
    4288         220 :       slot->value_ = arguments;
    4289         220 :       return arguments;
    4290             :     }
    4291             :     case TranslatedValue::kCapturedObject: {
    4292             :       // The map must be a tagged object.
    4293        2030 :       CHECK(frame->values_[*value_index].kind() == TranslatedValue::kTagged);
    4294        6090 :       CHECK(frame->values_[*value_index].GetValue()->IsMap());
    4295        2030 :       return MaterializeCapturedObjectAt(slot, frame_index, value_index);
    4296             :     }
    4297             :     case TranslatedValue::kDuplicatedObject: {
    4298             :       int object_index = slot->object_index();
    4299          12 :       TranslatedState::ObjectPosition pos = object_positions_[object_index];
    4300             : 
    4301             :       // Make sure the duplicate is refering to a previous object.
    4302          12 :       CHECK(pos.frame_index_ < frame_index ||
    4303             :             (pos.frame_index_ == frame_index &&
    4304             :              pos.value_index_ < *value_index - 1));
    4305             : 
    4306             :       Handle<Object> object =
    4307          24 :           frames_[pos.frame_index_].values_[pos.value_index_].GetValue();
    4308             : 
    4309             :       // The object should have a (non-sentinel) value.
    4310          24 :       CHECK(!object.is_null() &&
    4311             :             !object.is_identical_to(isolate_->factory()->arguments_marker()));
    4312             : 
    4313          12 :       slot->value_ = object;
    4314          12 :       return object;
    4315             :     }
    4316             : 
    4317             :     case TranslatedValue::kInvalid:
    4318           0 :       UNREACHABLE();
    4319             :       break;
    4320             :   }
    4321             : 
    4322           0 :   FATAL("We should never get here - unexpected deopt slot kind.");
    4323             :   return Handle<Object>::null();
    4324             : }
    4325             : 
    4326        1680 : Handle<Object> TranslatedState::MaterializeObjectAt(int object_index) {
    4327        1680 :   CHECK_LT(static_cast<size_t>(object_index), object_positions_.size());
    4328        1680 :   TranslatedState::ObjectPosition pos = object_positions_[object_index];
    4329        1680 :   return MaterializeAt(pos.frame_index_, &(pos.value_index_));
    4330             : }
    4331             : 
    4332         220 : bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result,
    4333             :                                           int frame_index) {
    4334         220 :   if (frame_index == 0) {
    4335             :     // Top level frame -> we need to go to the parent frame on the stack.
    4336         123 :     if (!has_adapted_arguments_) return false;
    4337             : 
    4338             :     // This is top level frame, so we need to go to the stack to get
    4339             :     // this function's argument. (Note that this relies on not inlining
    4340             :     // recursive functions!)
    4341             :     Handle<JSFunction> function =
    4342         207 :         Handle<JSFunction>::cast(frames_[frame_index].front().GetValue());
    4343          55 :     *result = Accessors::FunctionGetArguments(function);
    4344          55 :     return true;
    4345             :   } else {
    4346         194 :     TranslatedFrame* previous_frame = &(frames_[frame_index]);
    4347          97 :     if (previous_frame->kind() != TranslatedFrame::kArgumentsAdaptor) {
    4348             :       return false;
    4349             :     }
    4350             :     // We get the adapted arguments from the parent translation.
    4351             :     int length = previous_frame->height();
    4352             :     Handle<JSFunction> function =
    4353           0 :         Handle<JSFunction>::cast(previous_frame->front().GetValue());
    4354             :     Handle<JSObject> arguments =
    4355           0 :         isolate_->factory()->NewArgumentsObject(function, length);
    4356           0 :     Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
    4357           0 :     arguments->set_elements(*array);
    4358             :     TranslatedFrame::iterator arg_iterator = previous_frame->begin();
    4359             :     arg_iterator++;  // Skip function.
    4360           0 :     for (int i = 0; i < length; ++i) {
    4361           0 :       Handle<Object> value = arg_iterator->GetValue();
    4362           0 :       array->set(i, *value);
    4363             :       arg_iterator++;
    4364             :     }
    4365           0 :     CHECK(arg_iterator == previous_frame->end());
    4366           0 :     *result = arguments;
    4367           0 :     return true;
    4368             :   }
    4369             : }
    4370             : 
    4371       13597 : TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex(
    4372             :     int jsframe_index, int* args_count) {
    4373       85422 :   for (size_t i = 0; i < frames_.size(); i++) {
    4374       85422 :     if (frames_[i].kind() == TranslatedFrame::kFunction ||
    4375             :         frames_[i].kind() == TranslatedFrame::kInterpretedFunction) {
    4376       33079 :       if (jsframe_index > 0) {
    4377       19482 :         jsframe_index--;
    4378             :       } else {
    4379             :         // We have the JS function frame, now check if it has arguments
    4380             :         // adaptor.
    4381       27194 :         if (i > 0 &&
    4382       27194 :             frames_[i - 1].kind() == TranslatedFrame::kArgumentsAdaptor) {
    4383        5062 :           *args_count = frames_[i - 1].height();
    4384        2531 :           return &(frames_[i - 1]);
    4385             :         }
    4386             :         *args_count =
    4387       11066 :             frames_[i].shared_info()->internal_formal_parameter_count() + 1;
    4388       11066 :         return &(frames_[i]);
    4389             :       }
    4390             :     }
    4391             :   }
    4392             :   return nullptr;
    4393             : }
    4394             : 
    4395         111 : void TranslatedState::StoreMaterializedValuesAndDeopt(JavaScriptFrame* frame) {
    4396             :   MaterializedObjectStore* materialized_store =
    4397         111 :       isolate_->materialized_object_store();
    4398             :   Handle<FixedArray> previously_materialized_objects =
    4399         111 :       materialized_store->Get(stack_frame_pointer_);
    4400             : 
    4401         111 :   Handle<Object> marker = isolate_->factory()->arguments_marker();
    4402             : 
    4403         111 :   int length = static_cast<int>(object_positions_.size());
    4404             :   bool new_store = false;
    4405         111 :   if (previously_materialized_objects.is_null()) {
    4406             :     previously_materialized_objects =
    4407         111 :         isolate_->factory()->NewFixedArray(length);
    4408         325 :     for (int i = 0; i < length; i++) {
    4409         214 :       previously_materialized_objects->set(i, *marker);
    4410             :     }
    4411             :     new_store = true;
    4412             :   }
    4413             : 
    4414         111 :   CHECK_EQ(length, previously_materialized_objects->length());
    4415             : 
    4416             :   bool value_changed = false;
    4417         214 :   for (int i = 0; i < length; i++) {
    4418         214 :     TranslatedState::ObjectPosition pos = object_positions_[i];
    4419             :     TranslatedValue* value_info =
    4420         325 :         &(frames_[pos.frame_index_].values_[pos.value_index_]);
    4421             : 
    4422         214 :     CHECK(value_info->IsMaterializedObject());
    4423             : 
    4424         214 :     Handle<Object> value(value_info->GetRawValue(), isolate_);
    4425             : 
    4426         214 :     if (!value.is_identical_to(marker)) {
    4427         189 :       if (previously_materialized_objects->get(i) == *marker) {
    4428         189 :         previously_materialized_objects->set(i, *value);
    4429             :         value_changed = true;
    4430             :       } else {
    4431           0 :         CHECK(previously_materialized_objects->get(i) == *value);
    4432             :       }
    4433             :     }
    4434             :   }
    4435         111 :   if (new_store && value_changed) {
    4436             :     materialized_store->Set(stack_frame_pointer_,
    4437         111 :                             previously_materialized_objects);
    4438         111 :     CHECK(frames_[0].kind() == TranslatedFrame::kFunction ||
    4439             :           frames_[0].kind() == TranslatedFrame::kInterpretedFunction ||
    4440             :           frames_[0].kind() == TranslatedFrame::kTailCallerFunction);
    4441         111 :     CHECK_EQ(frame->function(), frames_[0].front().GetRawValue());
    4442         111 :     Deoptimizer::DeoptimizeFunction(frame->function(), frame->LookupCode());
    4443             :   }
    4444         111 : }
    4445             : 
    4446      187171 : void TranslatedState::UpdateFromPreviouslyMaterializedObjects() {
    4447             :   MaterializedObjectStore* materialized_store =
    4448      187171 :       isolate_->materialized_object_store();
    4449             :   Handle<FixedArray> previously_materialized_objects =
    4450      187171 :       materialized_store->Get(stack_frame_pointer_);
    4451             : 
    4452             :   // If we have no previously materialized objects, there is nothing to do.
    4453      374342 :   if (previously_materialized_objects.is_null()) return;
    4454             : 
    4455         111 :   Handle<Object> marker = isolate_->factory()->arguments_marker();
    4456             : 
    4457         111 :   int length = static_cast<int>(object_positions_.size());
    4458         111 :   CHECK_EQ(length, previously_materialized_objects->length());
    4459             : 
    4460         214 :   for (int i = 0; i < length; i++) {
    4461             :     // For a previously materialized objects, inject their value into the
    4462             :     // translated values.
    4463         214 :     if (previously_materialized_objects->get(i) != *marker) {
    4464         189 :       TranslatedState::ObjectPosition pos = object_positions_[i];
    4465             :       TranslatedValue* value_info =
    4466         189 :           &(frames_[pos.frame_index_].values_[pos.value_index_]);
    4467         189 :       CHECK(value_info->IsMaterializedObject());
    4468             : 
    4469             :       value_info->value_ =
    4470         378 :           Handle<Object>(previously_materialized_objects->get(i), isolate_);
    4471             :     }
    4472             :   }
    4473             : }
    4474             : 
    4475             : }  // namespace internal
    4476             : }  // namespace v8

Generated by: LCOV version 1.10