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