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