13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Redistribution and use in source and binary forms, with or without 3b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// modification, are permitted provided that the following conditions are 4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// met: 5b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions of source code must retain the above copyright 7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// notice, this list of conditions and the following disclaimer. 8b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions in binary form must reproduce the above 9b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// copyright notice, this list of conditions and the following 10b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// disclaimer in the documentation and/or other materials provided 11b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// with the distribution. 12b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Neither the name of Google Inc. nor the names of its 13b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// contributors may be used to endorse or promote products derived 14b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// from this software without specific prior written permission. 15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "v8.h" 29b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "codegen.h" 31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h" 32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "disasm.h" 33b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "full-codegen.h" 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "global-handles.h" 35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "macro-assembler.h" 36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "prettyprinter.h" 37b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 { 40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal { 41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDeoptimizerData::DeoptimizerData() { 4344f0eee88ff00398ff7f715fab053374d808c90dSteve Block eager_deoptimization_entry_code_ = NULL; 4444f0eee88ff00398ff7f715fab053374d808c90dSteve Block lazy_deoptimization_entry_code_ = NULL; 4544f0eee88ff00398ff7f715fab053374d808c90dSteve Block current_ = NULL; 4644f0eee88ff00398ff7f715fab053374d808c90dSteve Block deoptimizing_code_list_ = NULL; 473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch deoptimized_frame_info_ = NULL; 493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 51b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 52b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDeoptimizerData::~DeoptimizerData() { 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (eager_deoptimization_entry_code_ != NULL) { 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate::Current()->memory_allocator()->Free( 563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch eager_deoptimization_entry_code_); 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block eager_deoptimization_entry_code_ = NULL; 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (lazy_deoptimization_entry_code_ != NULL) { 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate::Current()->memory_allocator()->Free( 613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch lazy_deoptimization_entry_code_); 6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block lazy_deoptimization_entry_code_ = NULL; 6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid DeoptimizerData::Iterate(ObjectVisitor* v) { 693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (deoptimized_frame_info_ != NULL) { 703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch deoptimized_frame_info_->Iterate(v); 713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// We rely on this function not causing a GC. It is called from generated code 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// without having a real stack frame in place. 78b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer* Deoptimizer::New(JSFunction* function, 79b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType type, 80b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned bailout_id, 81b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address from, 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block int fp_to_sp_delta, 8344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate) { 8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate == Isolate::Current()); 8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Deoptimizer* deoptimizer = new Deoptimizer(isolate, 8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block function, 8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block type, 8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block bailout_id, 8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block from, 903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fp_to_sp_delta, 913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NULL); 9244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate->deoptimizer_data()->current_ == NULL); 9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->deoptimizer_data()->current_ = deoptimizer; 94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return deoptimizer; 95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDeoptimizer* Deoptimizer::Grab(Isolate* isolate) { 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate == Isolate::Current()); 10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Deoptimizer* result = isolate->deoptimizer_data()->current_; 101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(result != NULL); 102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result->DeleteFrameDescriptions(); 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->deoptimizer_data()->current_ = NULL; 104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result; 105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) { 1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (jsframe_index == 0) return 0; 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int frame_index = 0; 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (jsframe_index >= 0) { 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameDescription* frame = output_[frame_index]; 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) { 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jsframe_index--; 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_index++; 1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return frame_index - 1; 1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 1253fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochDeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame( 1263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JavaScriptFrame* frame, 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframe_index, 1283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Isolate* isolate) { 1293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(isolate == Isolate::Current()); 1303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(frame->is_optimized()); 1313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL); 1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the function and code from the frame. 1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JSFunction* function = JSFunction::cast(frame->function()); 1353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code* code = frame->LookupCode(); 1363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Locate the deoptimization point in the code. As we are at a call the 1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // return address must be at a place in the code with deoptimization support. 1392b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc()); 1402b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int deoptimization_index = safepoint_entry.deoptimization_index(); 1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(deoptimization_index != Safepoint::kNoDeoptimizationIndex); 1423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Always use the actual stack slots when calculating the fp to sp 1443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // delta adding two for the function and context. 1453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unsigned stack_slots = code->stack_slots(); 1463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unsigned fp_to_sp_delta = ((stack_slots + 2) * kPointerSize); 1473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Deoptimizer* deoptimizer = new Deoptimizer(isolate, 1493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch function, 1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Deoptimizer::DEBUGGER, 1513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch deoptimization_index, 1523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch frame->pc(), 1533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fp_to_sp_delta, 1543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code); 1553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Address tos = frame->fp() - fp_to_sp_delta; 1563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch deoptimizer->FillInputFrame(tos, frame); 1573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Calculate the output frames. 1593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Deoptimizer::ComputeOutputFrames(deoptimizer); 1603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Create the GC safe output frame information and register it for GC 1623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // handling. 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_LT(jsframe_index, deoptimizer->jsframe_count()); 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Convert JS frame index into frame index. 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index); 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_arguments_adaptor = 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_index > 0 && 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deoptimizer->output_[frame_index - 1]->GetFrameType() == 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StackFrame::ARGUMENTS_ADAPTOR; 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int construct_offset = has_arguments_adaptor ? 2 : 1; 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_construct_stub = 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_index >= construct_offset && 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deoptimizer->output_[frame_index - construct_offset]->GetFrameType() == 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StackFrame::CONSTRUCT; 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizedFrameInfo* info = new DeoptimizedFrameInfo(deoptimizer, 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_index, 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_arguments_adaptor, 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_construct_stub); 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate->deoptimizer_data()->deoptimized_frame_info_ = info; 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the "simulated" top and size for the requested frame. 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameDescription* parameters_frame = 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deoptimizer->output_[ 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_arguments_adaptor ? (frame_index - 1) : frame_index]; 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t parameters_size = (info->parameters_count() + 1) * kPointerSize; 1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address parameters_top = reinterpret_cast<Address>( 1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parameters_frame->GetTop() + (parameters_frame->GetFrameSize() - 1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parameters_size)); 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t expressions_size = info->expression_count() * kPointerSize; 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address expressions_top = reinterpret_cast<Address>( 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deoptimizer->output_[frame_index]->GetTop()); 1983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Done with the GC-unsafe frame descriptions. This re-enables allocation. 2003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch deoptimizer->DeleteFrameDescriptions(); 2013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Allocate a heap number for the doubles belonging to this frame. 2033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame( 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parameters_top, parameters_size, expressions_top, expressions_size, info); 2053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Finished using the deoptimizer instance. 2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch delete deoptimizer; 2083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return info; 2103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 2113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info, 2143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Isolate* isolate) { 2153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(isolate == Isolate::Current()); 2163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == info); 2173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch delete info; 2183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL; 2193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 2203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, 223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int count, 224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType type) { 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TableEntryGenerator generator(masm, type, count); 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch generator.Generate(); 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass DeoptimizingVisitor : public OptimizedFunctionVisitor { 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void EnterContext(Context* context) { 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[deoptimize context: %" V8PRIxPTR "]\n", 235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<intptr_t>(context)); 236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void VisitFunction(JSFunction* function) { 240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Deoptimizer::DeoptimizeFunction(function); 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void LeaveContext(Context* context) { 244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch context->ClearOptimizedFunctions(); 245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DeoptimizeAll() { 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AssertNoAllocation no_allocation; 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[deoptimize all contexts]\n"); 254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizingVisitor visitor; 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VisitAllOptimizedFunctions(&visitor); 258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DeoptimizeGlobalObject(JSObject* object) { 262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AssertNoAllocation no_allocation; 263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizingVisitor visitor; 265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VisitAllOptimizedFunctionsForGlobalObject(object, &visitor); 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::VisitAllOptimizedFunctionsForContext( 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Context* context, OptimizedFunctionVisitor* visitor) { 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AssertNoAllocation no_allocation; 272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(context->IsGlobalContext()); 274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch visitor->EnterContext(context); 276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run through the list of optimized functions and deoptimize them. 277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* element = context->OptimizedFunctionsListHead(); 278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (!element->IsUndefined()) { 279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* element_function = JSFunction::cast(element); 280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the next link before deoptimizing as deoptimizing will clear the 281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // next link. 282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch element = element_function->next_function_link(); 283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch visitor->VisitFunction(element_function); 284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch visitor->LeaveContext(context); 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::VisitAllOptimizedFunctionsForGlobalObject( 290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSObject* object, OptimizedFunctionVisitor* visitor) { 291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AssertNoAllocation no_allocation; 292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (object->IsJSGlobalProxy()) { 294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* proto = object->GetPrototype(); 295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(proto->IsJSGlobalObject()); 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VisitAllOptimizedFunctionsForContext( 297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GlobalObject::cast(proto)->global_context(), visitor); 298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (object->IsGlobalObject()) { 299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VisitAllOptimizedFunctionsForContext( 300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GlobalObject::cast(object)->global_context(), visitor); 301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::VisitAllOptimizedFunctions( 306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch OptimizedFunctionVisitor* visitor) { 307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AssertNoAllocation no_allocation; 308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run through the list of all global contexts and deoptimize. 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* context = Isolate::Current()->heap()->global_contexts_list(); 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!context->IsUndefined()) { 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // GC can happen when the context is not fully initialized, 3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // so the global field of the context can be undefined. 3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* global = Context::cast(context)->get(Context::GLOBAL_INDEX); 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!global->IsUndefined()) { 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitAllOptimizedFunctionsForGlobalObject(JSObject::cast(global), 3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch visitor); 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); 320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::HandleWeakDeoptimizedCode( 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Persistent<v8::Value> obj, void* data) { 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizingCodeListNode* node = 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<DeoptimizingCodeListNode*>(data); 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch RemoveDeoptimizingCode(*node->code()); 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block node = Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_; 331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (node != NULL) { 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(node != reinterpret_cast<DeoptimizingCodeListNode*>(data)); 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch node = node->next(); 334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) { 340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch deoptimizer->DoComputeOutputFrames(); 341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 34444f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDeoptimizer::Deoptimizer(Isolate* isolate, 34544f0eee88ff00398ff7f715fab053374d808c90dSteve Block JSFunction* function, 346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType type, 347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned bailout_id, 348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address from, 3493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int fp_to_sp_delta, 3503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code* optimized_code) 35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(isolate), 35244f0eee88ff00398ff7f715fab053374d808c90dSteve Block function_(function), 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bailout_id_(bailout_id), 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bailout_type_(type), 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch from_(from), 356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch fp_to_sp_delta_(fp_to_sp_delta), 3573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch input_(NULL), 358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_count_(0), 3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jsframe_count_(0), 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_(NULL), 3618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch deferred_heap_numbers_(0) { 362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt && type != OSR) { 3633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (type == DEBUGGER) { 3643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrintF("**** DEOPT FOR DEBUGGER: "); 3653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 3663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrintF("**** DEOPT: "); 3673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->PrintName(); 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n", 370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bailout_id, 371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<intptr_t>(from), 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch fp_to_sp_delta - (2 * kPointerSize)); 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (FLAG_trace_osr && type == OSR) { 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("**** OSR: "); 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->PrintName(); 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" at ast id #%u, address 0x%" V8PRIxPTR ", frame size %d\n", 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bailout_id, 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<intptr_t>(from), 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch fp_to_sp_delta - (2 * kPointerSize)); 380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Find the optimized code. 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (type == EAGER) { 383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(from == NULL); 384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch optimized_code_ = function_->code(); 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_deopt && FLAG_code_comments) { 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Print instruction associated with this bailout. 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* last_comment = NULL; 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int mask = RelocInfo::ModeMask(RelocInfo::COMMENT) 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch | RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (RelocIterator it(optimized_code_, mask); !it.done(); it.next()) { 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo* info = it.rinfo(); 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (info->rmode() == RelocInfo::COMMENT) { 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch last_comment = reinterpret_cast<const char*>(info->data()); 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (info->rmode() == RelocInfo::RUNTIME_ENTRY) { 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned id = Deoptimizer::GetDeoptimizationId( 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->target_address(), Deoptimizer::EAGER); 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (id == bailout_id && last_comment != NULL) { 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(" %s\n", last_comment); 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (type == LAZY) { 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch optimized_code_ = FindDeoptimizingCodeFromAddress(from); 407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(optimized_code_ != NULL); 408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (type == OSR) { 409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The function has already been optimized and we're transitioning 410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // from the unoptimized shared version to the optimized one in the 411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // function. The return address (from) points to unoptimized code. 412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch optimized_code_ = function_->code(); 413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(optimized_code_->kind() == Code::OPTIMIZED_FUNCTION); 414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(!optimized_code_->contains(from)); 4153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (type == DEBUGGER) { 4163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch optimized_code_ = optimized_code; 4173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(optimized_code_->contains(from)); 418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 41944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(HEAP->allow_allocation(false)); 420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned size = ComputeInputFrameSize(); 421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_ = new(size) FrameDescription(size, function); 4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch input_->SetFrameType(StackFrame::JAVA_SCRIPT); 423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer::~Deoptimizer() { 427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(input_ == NULL && output_ == NULL); 428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DeleteFrameDescriptions() { 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch delete input_; 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < output_count_; ++i) { 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (output_[i] != input_) delete output_[i]; 435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch delete[] output_; 437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_ = NULL; 438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_ = NULL; 43944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!HEAP->allow_allocation(true)); 440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochAddress Deoptimizer::GetDeoptimizationEntry(int id, BailoutType type) { 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(id >= 0); 445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (id >= kNumberOfEntries) return NULL; 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk* base = NULL; 44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); 448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (type == EAGER) { 44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (data->eager_deoptimization_entry_code_ == NULL) { 45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block data->eager_deoptimization_entry_code_ = CreateCode(type); 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 45244f0eee88ff00398ff7f715fab053374d808c90dSteve Block base = data->eager_deoptimization_entry_code_; 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 45444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (data->lazy_deoptimization_entry_code_ == NULL) { 45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block data->lazy_deoptimization_entry_code_ = CreateCode(type); 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 45744f0eee88ff00398ff7f715fab053374d808c90dSteve Block base = data->lazy_deoptimization_entry_code_; 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<Address>(base->area_start()) + (id * table_entry_size_); 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) { 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk* base = NULL; 46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); 467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (type == EAGER) { 46844f0eee88ff00398ff7f715fab053374d808c90dSteve Block base = data->eager_deoptimization_entry_code_; 469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 47044f0eee88ff00398ff7f715fab053374d808c90dSteve Block base = data->lazy_deoptimization_entry_code_; 471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (base == NULL || 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch addr < base->area_start() || 4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch addr >= base->area_start() + 475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch (kNumberOfEntries * table_entry_size_)) { 476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return kNotDeoptimizationEntry; 477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT_EQ(0, 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(addr - base->area_start()) % table_entry_size_); 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return static_cast<int>(addr - base->area_start()) / table_entry_size_; 481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4849fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockint Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data, 4859fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block unsigned id, 4869fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block SharedFunctionInfo* shared) { 487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(kasperl): For now, we do a simple linear search for the PC 488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // offset associated with the given node id. This should probably be 489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // changed to a binary search. 490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = data->DeoptPoints(); 491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Smi* smi_id = Smi::FromInt(id); 492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < length; i++) { 493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (data->AstId(i) == smi_id) { 494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return data->PcAndState(i)->value(); 495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[couldn't find pc offset for node=%u]\n", id); 498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[method: %s]\n", *shared->DebugName()->ToCString()); 499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Print the source code if available. 500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HeapStringAllocator string_allocator; 501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StringStream stream(&string_allocator); 502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->SourceCodePrint(&stream, -1); 503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[source:\n%s\n]", *stream.ToCString()); 504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return -1; 507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 51044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) { 511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = 0; 51244f0eee88ff00398ff7f715fab053374d808c90dSteve Block DeoptimizingCodeListNode* node = 51344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->deoptimizer_data()->deoptimizing_code_list_; 514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (node != NULL) { 515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch length++; 516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch node = node->next(); 517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return length; 519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// We rely on this function not causing a GC. It is called from generated code 5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// without having a real stack frame in place. 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DoComputeOutputFrames() { 525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (bailout_type_ == OSR) { 526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DoComputeOsrOutputFrame(); 527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Print some helpful diagnostic information. 531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int64_t start = OS::Ticks(); 532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ", 534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch (bailout_type_ == LAZY ? " (lazy)" : ""), 535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<intptr_t>(function_)); 536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function_->PrintName(); 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" @%d]\n", bailout_id_); 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Determine basic deoptimization information. The optimized frame is 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // described by the input data. 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationInputData* input_data = 543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationInputData::cast(optimized_code_->deoptimization_data()); 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned node_id = input_data->AstId(bailout_id_)->value(); 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ByteArray* translations = input_data->TranslationByteArray(); 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned translation_index = 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_data->TranslationIndex(bailout_id_)->value(); 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Do the input frame to output frame(s) translation. 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationIterator iterator(translations, translation_index); 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Translation::Opcode opcode = 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<Translation::Opcode>(iterator.Next()); 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(Translation::BEGIN == opcode); 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch USE(opcode); 555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Read the number of output frames and allocate an array for their 556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // descriptions. 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int count = iterator.Next(); 5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch iterator.Next(); // Drop JS frames count. 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(output_ == NULL); 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_ = new FrameDescription*[count]; 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < count; ++i) { 562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[i] = NULL; 563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_count_ = count; 565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Translate each output frame. 567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < count; ++i) { 5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Read the ast node id, function, and frame height for this output frame. 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Translation::Opcode opcode = 5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<Translation::Opcode>(iterator.Next()); 5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (opcode) { 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::JS_FRAME: 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoComputeJSFrame(&iterator, i); 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jsframe_count_++; 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::ARGUMENTS_ADAPTOR_FRAME: 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoComputeArgumentsAdaptorFrame(&iterator, i); 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::CONSTRUCT_STUB_FRAME: 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoComputeConstructStubFrame(&iterator, i); 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Print some helpful diagnostic information. 589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double ms = static_cast<double>(OS::Ticks() - start) / 1000; 591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int index = output_count_ - 1; // Index of the topmost frame. 592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function = output_[index]->GetFunction(); 593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ", 594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<intptr_t>(function)); 595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->PrintName(); 596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" => node=%u, pc=0x%08" V8PRIxPTR ", state=%s, took %0.3f ms]\n", 597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch node_id, 598b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[index]->GetPc(), 599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FullCodeGenerator::State2String( 600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<FullCodeGenerator::State>( 601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[index]->GetState()->value())), 602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ms); 603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid Deoptimizer::MaterializeHeapNumbers() { 6083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT_NE(DEBUGGER, bailout_type_); 6098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch for (int i = 0; i < deferred_heap_numbers_.length(); i++) { 6108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; 6118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 6128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (FLAG_trace_deopt) { 6138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch PrintF("Materializing a new heap number %p [%e] in slot %p\n", 6148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch reinterpret_cast<void*>(*num), 6158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch d.value(), 6168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch d.slot_address()); 6178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Memory::Object_at(d.slot_address()) = *num; 620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 6253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( 6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address parameters_top, 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t parameters_size, 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address expressions_top, 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t expressions_size, 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizedFrameInfo* info) { 6313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT_EQ(DEBUGGER, bailout_type_); 6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address parameters_bottom = parameters_top + parameters_size; 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address expressions_bottom = expressions_top + expressions_size; 6343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < deferred_heap_numbers_.length(); i++) { 6353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; 6363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check of the heap number to materialize actually belong to the frame 6383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // being extracted. 6393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Address slot = d.slot_address(); 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (parameters_top <= slot && slot < parameters_bottom) { 6413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int index = (info->parameters_count() - 1) - 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(slot - parameters_top) / kPointerSize; 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (FLAG_trace_deopt) { 6473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrintF("Materializing a new heap number %p [%e] in slot %p" 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "for parameter slot #%d\n", 6493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch reinterpret_cast<void*>(*num), 6503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch d.value(), 6513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch d.slot_address(), 6523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch index); 6533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->SetParameter(index, *num); 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (expressions_top <= slot && slot < expressions_bottom) { 6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int index = info->expression_count() - 1 - 6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(slot - expressions_top) / kPointerSize; 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_deopt) { 6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Materializing a new heap number %p [%e] in slot %p" 6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "for expression slot #%d\n", 6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<void*>(*num), 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch d.value(), 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch d.slot_address(), 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch index); 6693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->SetExpression(index, *num); 6723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 6753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 6763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, 679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int frame_index, 680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned output_offset) { 681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch disasm::NameConverter converter; 682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // A GC-safe temporary placeholder that we can put in the output frame. 683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); 684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Ignore commands marked as duplicate and act on the first non-duplicate. 686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Translation::Opcode opcode = 687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<Translation::Opcode>(iterator->Next()); 688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (opcode == Translation::DUPLICATE) { 689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch opcode = static_cast<Translation::Opcode>(iterator->Next()); 690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch iterator->Skip(Translation::NumberOfOperandsFor(opcode)); 691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch opcode = static_cast<Translation::Opcode>(iterator->Next()); 692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch switch (opcode) { 695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::BEGIN: 6963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::JS_FRAME: 6973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::ARGUMENTS_ADAPTOR_FRAME: 6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::CONSTRUCT_STUB_FRAME: 699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::DUPLICATE: 700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 702b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::REGISTER: { 704b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int input_reg = iterator->Next(); 705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t input_value = input_->GetRegister(input_reg); 706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF( 7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", 709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->GetTop() + output_offset, 710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset, 711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_value, 712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch converter.NameOfCPURegister(input_reg)); 7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Object*>(input_value)->ShortPrint(); 7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("\n"); 715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, input_value); 717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 719b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 720b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::INT32_REGISTER: { 721b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int input_reg = iterator->Next(); 722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t value = input_->GetRegister(input_reg); 723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_smi = Smi::IsValid(value); 724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 725b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF( 726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", 727b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->GetTop() + output_offset, 728b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset, 729b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch value, 730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch converter.NameOfCPURegister(input_reg), 731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch is_smi ? "smi" : "heap number"); 732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (is_smi) { 734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t tagged_value = 735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, tagged_value); 737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We save the untagged value on the side and store a GC-safe 739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // temporary placeholder in the frame. 7408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch AddDoubleValue(output_[frame_index]->GetTop() + output_offset, 7418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<double>(static_cast<int32_t>(value))); 742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::DOUBLE_REGISTER: { 748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int input_reg = iterator->Next(); 749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double value = input_->GetDoubleRegister(input_reg); 750b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n", 752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->GetTop() + output_offset, 753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset, 754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch value, 755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DoubleRegister::AllocationIndexToString(input_reg)); 756b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 757b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We save the untagged value on the side and store a GC-safe 758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // temporary placeholder in the frame. 7598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); 760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 763b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::STACK_SLOT: { 765b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int input_slot_index = iterator->Next(); 766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned input_offset = 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch input_->GetOffsetFromSlotIndex(input_slot_index); 768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t input_value = input_->GetFrameSlot(input_offset); 769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" 0x%08" V8PRIxPTR ": ", 771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->GetTop() + output_offset); 7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d] ", 773b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset, 774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_value, 775b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_offset); 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Object*>(input_value)->ShortPrint(); 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("\n"); 778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, input_value); 780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 782b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::INT32_STACK_SLOT: { 784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int input_slot_index = iterator->Next(); 785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned input_offset = 7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch input_->GetOffsetFromSlotIndex(input_slot_index); 787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t value = input_->GetFrameSlot(input_offset); 788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_smi = Smi::IsValid(value); 789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" 0x%08" V8PRIxPTR ": ", 791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->GetTop() + output_offset); 792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[top + %d] <- %" V8PRIdPTR " ; [esp + %d] (%s)\n", 793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset, 794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch value, 795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_offset, 796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch is_smi ? "smi" : "heap number"); 797b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 798b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (is_smi) { 799b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t tagged_value = 800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, tagged_value); 802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We save the untagged value on the side and store a GC-safe 804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // temporary placeholder in the frame. 8058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch AddDoubleValue(output_[frame_index]->GetTop() + output_offset, 8068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<double>(static_cast<int32_t>(value))); 807b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 810b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 812b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::DOUBLE_STACK_SLOT: { 813b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int input_slot_index = iterator->Next(); 814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned input_offset = 8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch input_->GetOffsetFromSlotIndex(input_slot_index); 816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double value = input_->GetDoubleFrameSlot(input_offset); 817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [esp + %d]\n", 819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->GetTop() + output_offset, 820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset, 821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch value, 822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_offset); 823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We save the untagged value on the side and store a GC-safe 825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // temporary placeholder in the frame. 8268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); 827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 828b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::LITERAL: { 832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* literal = ComputeLiteral(iterator->Next()); 833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 834b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", 835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->GetTop() + output_offset, 836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset); 837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch literal->ShortPrint(); 838b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" ; literal\n"); 839b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 840b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t value = reinterpret_cast<intptr_t>(literal); 841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, value); 842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::ARGUMENTS_OBJECT: { 846086aeeaae12517475c22695a200be45495516549Ben Murdoch // Use the arguments marker value as a sentinel and fill in the arguments 847086aeeaae12517475c22695a200be45495516549Ben Murdoch // object after the deoptimized frame is built. 848b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_deopt) { 849b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", 850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->GetTop() + output_offset, 851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset); 85244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->arguments_marker()->ShortPrint(); 853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" ; arguments object\n"); 854b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 85544f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t value = reinterpret_cast<intptr_t>( 85644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->arguments_marker()); 857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_[frame_index]->SetFrameSlot(output_offset, value); 858b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 863b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator, 865b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int* input_offset) { 866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch disasm::NameConverter converter; 867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameDescription* output = output_[0]; 868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 869b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The input values are all part of the unoptimized frame so they 870b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // are all tagged pointers. 871b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uintptr_t input_value = input_->GetFrameSlot(*input_offset); 872b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* input_object = reinterpret_cast<Object*>(input_value); 873b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 874b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Translation::Opcode opcode = 875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<Translation::Opcode>(iterator->Next()); 876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool duplicate = (opcode == Translation::DUPLICATE); 877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (duplicate) { 878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch opcode = static_cast<Translation::Opcode>(iterator->Next()); 879b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 880b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 881b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch switch (opcode) { 882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::BEGIN: 8833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::JS_FRAME: 8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::ARGUMENTS_ADAPTOR_FRAME: 8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::CONSTRUCT_STUB_FRAME: 886b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::DUPLICATE: 887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); // Malformed input. 888b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::REGISTER: { 891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int output_reg = iterator->Next(); 892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 8931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", 894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch converter.NameOfCPURegister(output_reg), 895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_value, 896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *input_offset); 897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 898b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output->SetRegister(output_reg, input_value); 899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch break; 900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 902b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::INT32_REGISTER: { 903b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Abort OSR if we don't have a number. 904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!input_object->IsNumber()) return false; 905b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int output_reg = iterator->Next(); 907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int int32_value = input_object->IsSmi() 908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ? Smi::cast(input_object)->value() 909b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : FastD2I(input_object->Number()); 910b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Abort the translation if the conversion lost information. 911b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!input_object->IsSmi() && 912b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FastI2D(int32_value) != input_object->Number()) { 913b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 914b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("**** %g could not be converted to int32 ****\n", 915b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_object->Number()); 916b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 917b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 919b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 9201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block PrintF(" %s <- %d (int32) ; [sp + %d]\n", 921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch converter.NameOfCPURegister(output_reg), 922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int32_value, 923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *input_offset); 924b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output->SetRegister(output_reg, int32_value); 926b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch break; 927b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 928b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 929b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::DOUBLE_REGISTER: { 930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Abort OSR if we don't have a number. 931b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!input_object->IsNumber()) return false; 932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 933b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int output_reg = iterator->Next(); 934b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double double_value = input_object->Number(); 935b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 9361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block PrintF(" %s <- %g (double) ; [sp + %d]\n", 937b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DoubleRegister::AllocationIndexToString(output_reg), 938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double_value, 939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *input_offset); 940b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output->SetDoubleRegister(output_reg, double_value); 942b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch break; 943b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 945b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::STACK_SLOT: { 946b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int output_index = iterator->Next(); 947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned output_offset = 9483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch output->GetOffsetFromSlotIndex(output_index); 949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(" [sp + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", 951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset, 952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_value, 953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *input_offset); 9543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Object*>(input_value)->ShortPrint(); 9553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("\n"); 956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 957b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output->SetFrameSlot(output_offset, input_value); 958b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch break; 959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 961b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::INT32_STACK_SLOT: { 962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Abort OSR if we don't have a number. 963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!input_object->IsNumber()) return false; 964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int output_index = iterator->Next(); 966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned output_offset = 9673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch output->GetOffsetFromSlotIndex(output_index); 968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int int32_value = input_object->IsSmi() 969b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ? Smi::cast(input_object)->value() 970b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : DoubleToInt32(input_object->Number()); 971b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Abort the translation if the conversion lost information. 972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!input_object->IsSmi() && 973b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FastI2D(int32_value) != input_object->Number()) { 974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 975b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("**** %g could not be converted to int32 ****\n", 976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch input_object->Number()); 977b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 978b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 979b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 980b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 9811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block PrintF(" [sp + %d] <- %d (int32) ; [sp + %d]\n", 982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset, 983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int32_value, 984b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *input_offset); 985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 986b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output->SetFrameSlot(output_offset, int32_value); 987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch break; 988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::DOUBLE_STACK_SLOT: { 991b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kLowerOffset = 0 * kPointerSize; 992b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kUpperOffset = 1 * kPointerSize; 993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 994b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Abort OSR if we don't have a number. 995b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!input_object->IsNumber()) return false; 996b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 997b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int output_index = iterator->Next(); 998b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned output_offset = 9993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch output->GetOffsetFromSlotIndex(output_index); 1000b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double double_value = input_object->Number(); 1001b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uint64_t int_value = BitCast<uint64_t, double>(double_value); 1002b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int32_t lower = static_cast<int32_t>(int_value); 1003b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int32_t upper = static_cast<int32_t>(int_value >> kBitsPerInt); 1004b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 10051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block PrintF(" [sp + %d] <- 0x%08x (upper bits of %g) ; [sp + %d]\n", 1006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset + kUpperOffset, 1007b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch upper, 1008b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double_value, 1009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *input_offset); 10101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block PrintF(" [sp + %d] <- 0x%08x (lower bits of %g) ; [sp + %d]\n", 1011b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output_offset + kLowerOffset, 1012b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch lower, 1013b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double_value, 1014b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *input_offset); 1015b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1016b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output->SetFrameSlot(output_offset + kLowerOffset, lower); 1017b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch output->SetFrameSlot(output_offset + kUpperOffset, upper); 1018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch break; 1019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::LITERAL: { 1022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Just ignore non-materialized literals. 1023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch iterator->Next(); 1024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch break; 1025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Translation::ARGUMENTS_OBJECT: { 1028b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Optimized code assumes that the argument object has not been 1029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // materialized and so bypasses it when doing arguments access. 1030b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We should have bailed out before starting the frame 1031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // translation. 1032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 1033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 1034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!duplicate) *input_offset -= kPointerSize; 1038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 1039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid Deoptimizer::PatchStackCheckCode(Code* unoptimized_code, 10431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 10441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code) { 10451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Iterate over the stack check table and patch every stack check 10461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // call to an unconditional call to the replacement code. 10471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ASSERT(unoptimized_code->kind() == Code::FUNCTION); 10481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Address stack_check_cursor = unoptimized_code->instruction_start() + 10491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block unoptimized_code->stack_check_table_offset(); 10501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uint32_t table_length = Memory::uint32_at(stack_check_cursor); 10511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block stack_check_cursor += kIntSize; 10521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block for (uint32_t i = 0; i < table_length; ++i) { 10531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uint32_t pc_offset = Memory::uint32_at(stack_check_cursor + kIntSize); 10541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Address pc_after = unoptimized_code->instruction_start() + pc_offset; 10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchStackCheckCodeAt(unoptimized_code, 10563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pc_after, 10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch check_code, 10583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch replacement_code); 10591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block stack_check_cursor += 2 * kIntSize; 10601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 10611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 10621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 10631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 10641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid Deoptimizer::RevertStackCheckCode(Code* unoptimized_code, 10651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 10661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code) { 10671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Iterate over the stack check table and revert the patched 10681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // stack check calls. 10691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ASSERT(unoptimized_code->kind() == Code::FUNCTION); 10701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Address stack_check_cursor = unoptimized_code->instruction_start() + 10711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block unoptimized_code->stack_check_table_offset(); 10721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uint32_t table_length = Memory::uint32_at(stack_check_cursor); 10731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block stack_check_cursor += kIntSize; 10741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block for (uint32_t i = 0; i < table_length; ++i) { 10751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uint32_t pc_offset = Memory::uint32_at(stack_check_cursor + kIntSize); 10761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Address pc_after = unoptimized_code->instruction_start() + pc_offset; 10773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RevertStackCheckCodeAt(unoptimized_code, 10783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pc_after, 10793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch check_code, 10803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch replacement_code); 10811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block stack_check_cursor += 2 * kIntSize; 10821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 10831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 10841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 10851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned Deoptimizer::ComputeInputFrameSize() const { 1087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned fixed_size = ComputeFixedSize(function_); 1088b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The fp-to-sp delta already takes the context and the function 1089b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // into account so we have to avoid double counting them (-2). 1090b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize); 1091b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 1092b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (bailout_type_ == OSR) { 1093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(kasperl): It would be nice if we could verify that the 1094b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // size matches with the stack height we can compute based on the 1095b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // environment at the OSR entry. The code for that his built into 1096b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the DoComputeOsrOutputFrame function for now. 1097b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 1098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned stack_slots = optimized_code_->stack_slots(); 1099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned outgoing_size = ComputeOutgoingArgumentSize(); 1100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); 1101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 1103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result; 1104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const { 1108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The fixed part of the frame consists of the return address, frame 1109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // pointer, function, context, and all the incoming arguments. 11103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ComputeIncomingArgumentSize(function) + 11113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StandardFrameConstants::kFixedFrameSize; 1112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { 1116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The incoming arguments is the values for formal parameters and 1117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the receiver. Every slot contains a pointer. 1118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned arguments = function->shared()->formal_parameter_count() + 1; 1119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return arguments * kPointerSize; 1120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned Deoptimizer::ComputeOutgoingArgumentSize() const { 1124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationInputData* data = DeoptimizationInputData::cast( 1125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch optimized_code_->deoptimization_data()); 1126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned height = data->ArgumentsStackHeight(bailout_id_)->value(); 1127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return height * kPointerSize; 1128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochObject* Deoptimizer::ComputeLiteral(int index) const { 1132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationInputData* data = DeoptimizationInputData::cast( 1133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch optimized_code_->deoptimization_data()); 1134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FixedArray* literals = data->LiteralArray(); 1135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return literals->get(index); 1136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid Deoptimizer::AddDoubleValue(intptr_t slot_address, 1140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double value) { 11418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HeapNumberMaterializationDescriptor value_desc( 11428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch reinterpret_cast<Address>(slot_address), value); 11438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch deferred_heap_numbers_.Add(value_desc); 1144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11473ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMemoryChunk* Deoptimizer::CreateCode(BailoutType type) { 1148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We cannot run this if the serializer is enabled because this will 1149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // cause us to emit relocation information for the external 1150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // references. This is fine because the deoptimizer's code section 1151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // isn't meant to be serialized at all. 1152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(!Serializer::enabled()); 1153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler masm(Isolate::Current(), NULL, 16 * KB); 115544f0eee88ff00398ff7f715fab053374d808c90dSteve Block masm.set_emit_debug_code(false); 1156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type); 1157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CodeDesc desc; 1158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm.GetCode(&desc); 1159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(desc.reloc_size == 0); 1160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk* chunk = 11623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate::Current()->memory_allocator()->AllocateChunk(desc.instr_size, 11633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXECUTABLE, 11643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NULL); 11653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(chunk->area_size() >= desc.instr_size); 11663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (chunk == NULL) { 11673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch V8::FatalProcessOutOfMemory("Not enough memory for deoptimization table"); 11683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 11693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch memcpy(chunk->area_start(), desc.buffer, desc.instr_size); 11703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CPU::FlushICache(chunk->area_start(), desc.instr_size); 1171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return chunk; 1172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochCode* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) { 117644f0eee88ff00398ff7f715fab053374d808c90dSteve Block DeoptimizingCodeListNode* node = 117744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_; 1178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (node != NULL) { 1179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (node->code()->contains(addr)) return *node->code(); 1180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch node = node->next(); 1181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return NULL; 1183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::RemoveDeoptimizingCode(Code* code) { 118744f0eee88ff00398ff7f715fab053374d808c90dSteve Block DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); 118844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(data->deoptimizing_code_list_ != NULL); 1189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run through the code objects to find this one and remove it. 1190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizingCodeListNode* prev = NULL; 119144f0eee88ff00398ff7f715fab053374d808c90dSteve Block DeoptimizingCodeListNode* current = data->deoptimizing_code_list_; 1192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (current != NULL) { 1193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (*current->code() == code) { 1194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Unlink from list. If prev is NULL we are looking at the first element. 1195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (prev == NULL) { 119644f0eee88ff00398ff7f715fab053374d808c90dSteve Block data->deoptimizing_code_list_ = current->next(); 1197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 1198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch prev->set_next(current->next()); 1199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch delete current; 1201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 1202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Move to next in list. 1204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch prev = current; 1205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current = current->next(); 1206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Deoptimizing code is removed through weak callback. Each object is expected 1208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // to be removed once and only once. 1209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 1210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochFrameDescription::FrameDescription(uint32_t frame_size, 1214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function) 1215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : frame_size_(frame_size), 1216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function_(function), 1217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch top_(kZapUint32), 1218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pc_(kZapUint32), 12193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fp_(kZapUint32), 12203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch context_(kZapUint32) { 1221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Zap all the registers. 1222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int r = 0; r < Register::kNumRegisters; r++) { 1223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetRegister(r, kZapUint32); 1224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Zap all the slots. 1227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (unsigned o = 0; o < frame_size; o += kPointerSize) { 1228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetFrameSlot(o, kZapUint32); 1229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint FrameDescription::ComputeFixedSize() { 12343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return StandardFrameConstants::kFixedFrameSize + 12353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (ComputeParametersCount() + 1) * kPointerSize; 12363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochunsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) { 1240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (slot_index >= 0) { 1241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Local or spill slots. Skip the fixed part of the frame 1242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // including all arguments. 12433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned base = GetFrameSize() - ComputeFixedSize(); 1244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return base - ((slot_index + 1) * kPointerSize); 1245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 1246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Incoming parameter. 12473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arg_size = (ComputeParametersCount() + 1) * kPointerSize; 12483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned base = GetFrameSize() - arg_size; 1249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return base - ((slot_index + 1) * kPointerSize); 1250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint FrameDescription::ComputeParametersCount() { 12553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (type_) { 12563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case StackFrame::JAVA_SCRIPT: 12573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return function_->shared()->formal_parameter_count(); 12583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case StackFrame::ARGUMENTS_ADAPTOR: { 12593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Last slot contains number of incomming arguments as a smi. 12603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Can't use GetExpression(0) because it would cause infinite recursion. 12613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value(); 12623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 12653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 0; 12663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 12683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12703ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochObject* FrameDescription::GetParameter(int index) { 12713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(index >= 0); 12723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(index < ComputeParametersCount()); 12733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The slot indexes for incoming arguments are negative. 12743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount()); 12753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 12763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 12773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochunsigned FrameDescription::GetExpressionCount() { 12803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_); 12813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned size = GetFrameSize() - ComputeFixedSize(); 12823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return size / kPointerSize; 12833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 12843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12863ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochObject* FrameDescription::GetExpression(int index) { 12873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_); 12883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned offset = GetOffsetFromSlotIndex(index); 12893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 12903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 12913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid TranslationBuffer::Add(int32_t value) { 1294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Encode the sign bit in the least significant bit. 1295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_negative = (value < 0); 1296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uint32_t bits = ((is_negative ? -value : value) << 1) | 1297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<int32_t>(is_negative); 1298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Encode the individual bytes using the least significant bit of 1299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // each byte to indicate whether or not more bytes follow. 1300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch do { 1301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uint32_t next = bits >> 7; 1302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch contents_.Add(((bits << 1) & 0xFF) | (next != 0)); 1303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bits = next; 1304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } while (bits != 0); 1305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint32_t TranslationIterator::Next() { 1309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run through the bytes until we reach one with a least significant 1310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // bit of zero (marks the end). 1311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uint32_t bits = 0; 1312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; true; i += 7) { 131369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(HasNext()); 1314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uint8_t next = buffer_->get(index_++); 1315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bits |= (next >> 1) << i; 1316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if ((next & 1) == 0) break; 1317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The bits encode the sign in the least significant bit. 1319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_negative = (bits & 1) == 1; 1320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int32_t result = bits >> 1; 1321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return is_negative ? -result : result; 1322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHandle<ByteArray> TranslationBuffer::CreateByteArray() { 1326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = contents_.length(); 132744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<ByteArray> result = 132844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->factory()->NewByteArray(length, TENURED); 1329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length); 1330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result; 1331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Translation::BeginConstructStubFrame(int literal_id, unsigned height) { 13353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer_->Add(CONSTRUCT_STUB_FRAME); 13363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer_->Add(literal_id); 13373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer_->Add(height); 13383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) { 13423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer_->Add(ARGUMENTS_ADAPTOR_FRAME); 13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer_->Add(literal_id); 13443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer_->Add(height); 13453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Translation::BeginJSFrame(int node_id, int literal_id, unsigned height) { 13493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer_->Add(JS_FRAME); 1350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(node_id); 1351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(literal_id); 1352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(height); 1353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreRegister(Register reg) { 1357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(REGISTER); 1358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(reg.code()); 1359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32Register(Register reg) { 1363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(INT32_REGISTER); 1364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(reg.code()); 1365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreDoubleRegister(DoubleRegister reg) { 1369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(DOUBLE_REGISTER); 1370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(DoubleRegister::ToAllocationIndex(reg)); 1371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreStackSlot(int index) { 1375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(STACK_SLOT); 1376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(index); 1377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32StackSlot(int index) { 1381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(INT32_STACK_SLOT); 1382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(index); 1383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreDoubleStackSlot(int index) { 1387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(DOUBLE_STACK_SLOT); 1388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(index); 1389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreLiteral(int literal_id) { 1393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(LITERAL); 1394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(literal_id); 1395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreArgumentsObject() { 1399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(ARGUMENTS_OBJECT); 1400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::MarkDuplicate() { 1404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(DUPLICATE); 1405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint Translation::NumberOfOperandsFor(Opcode opcode) { 1409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch switch (opcode) { 1410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case ARGUMENTS_OBJECT: 1411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case DUPLICATE: 1412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return 0; 1413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case REGISTER: 1414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case INT32_REGISTER: 1415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case DOUBLE_REGISTER: 1416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case STACK_SLOT: 1417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case INT32_STACK_SLOT: 1418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case DOUBLE_STACK_SLOT: 1419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case LITERAL: 1420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return 1; 14213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case BEGIN: 14223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case ARGUMENTS_ADAPTOR_FRAME: 14233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CONSTRUCT_STUB_FRAME: 14243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 2; 14253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case JS_FRAME: 1426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return 3; 1427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 1429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return -1; 1430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 14333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) 1434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* Translation::StringFor(Opcode opcode) { 1436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch switch (opcode) { 1437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case BEGIN: 1438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "BEGIN"; 14393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case JS_FRAME: 14403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return "JS_FRAME"; 14413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case ARGUMENTS_ADAPTOR_FRAME: 14423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return "ARGUMENTS_ADAPTOR_FRAME"; 14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CONSTRUCT_STUB_FRAME: 14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return "CONSTRUCT_STUB_FRAME"; 1445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case REGISTER: 1446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "REGISTER"; 1447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case INT32_REGISTER: 1448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "INT32_REGISTER"; 1449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case DOUBLE_REGISTER: 1450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "DOUBLE_REGISTER"; 1451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case STACK_SLOT: 1452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "STACK_SLOT"; 1453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case INT32_STACK_SLOT: 1454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "INT32_STACK_SLOT"; 1455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case DOUBLE_STACK_SLOT: 1456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "DOUBLE_STACK_SLOT"; 1457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case LITERAL: 1458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "LITERAL"; 1459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case ARGUMENTS_OBJECT: 1460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "ARGUMENTS_OBJECT"; 1461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case DUPLICATE: 1462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return "DUPLICATE"; 1463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 1465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return ""; 1466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 1469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { 147244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GlobalHandles* global_handles = Isolate::Current()->global_handles(); 1473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Globalize the code object and make it weak. 147444f0eee88ff00398ff7f715fab053374d808c90dSteve Block code_ = Handle<Code>::cast(global_handles->Create(code)); 147544f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(reinterpret_cast<Object**>(code_.location()), 147644f0eee88ff00398ff7f715fab053374d808c90dSteve Block this, 147744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Deoptimizer::HandleWeakDeoptimizedCode); 1478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizingCodeListNode::~DeoptimizingCodeListNode() { 148244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GlobalHandles* global_handles = Isolate::Current()->global_handles(); 148344f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy(reinterpret_cast<Object**>(code_.location())); 1484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 14878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// We can't intermix stack decoding and allocations because 14888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// deoptimization infrastracture is not GC safe. 14898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Thus we build a temporary structure in malloced space. 14908b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochSlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator, 14918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch DeoptimizationInputData* data, 14928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch JavaScriptFrame* frame) { 14938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Translation::Opcode opcode = 14948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<Translation::Opcode>(iterator->Next()); 14958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 14968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch switch (opcode) { 14978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::BEGIN: 14983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::JS_FRAME: 14993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::ARGUMENTS_ADAPTOR_FRAME: 15003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Translation::CONSTRUCT_STUB_FRAME: 15018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Peeled off before getting here. 15028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch break; 15038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 15048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::ARGUMENTS_OBJECT: 15058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // This can be only emitted for local slots not for argument slots. 15068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch break; 15078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 15088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::REGISTER: 15098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::INT32_REGISTER: 15108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::DOUBLE_REGISTER: 15118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::DUPLICATE: 15128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // We are at safepoint which corresponds to call. All registers are 15138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // saved by caller so there would be no live registers at this 15148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // point. Thus these translation commands should not be used. 15158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch break; 15168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 15178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::STACK_SLOT: { 15188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int slot_index = iterator->Next(); 15198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address slot_addr = SlotAddress(frame, slot_index); 15208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return SlotRef(slot_addr, SlotRef::TAGGED); 15218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 15228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 15238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::INT32_STACK_SLOT: { 15248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int slot_index = iterator->Next(); 15258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address slot_addr = SlotAddress(frame, slot_index); 15268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return SlotRef(slot_addr, SlotRef::INT32); 15278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 15288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 15298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::DOUBLE_STACK_SLOT: { 15308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int slot_index = iterator->Next(); 15318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address slot_addr = SlotAddress(frame, slot_index); 15328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return SlotRef(slot_addr, SlotRef::DOUBLE); 15338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 15348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 15358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case Translation::LITERAL: { 15368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int literal_index = iterator->Next(); 15378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return SlotRef(data->LiteralArray()->get(literal_index)); 15388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 15398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 15408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 15418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch UNREACHABLE(); 15428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return SlotRef(); 15438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 15448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 15458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 15463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid SlotRef::ComputeSlotsForArguments(Vector<SlotRef>* args_slots, 15473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranslationIterator* it, 15483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizationInputData* data, 15493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JavaScriptFrame* frame) { 15503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Process the translation commands for the arguments. 15513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip the translation command for the receiver. 15533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it->Skip(Translation::NumberOfOperandsFor( 15543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<Translation::Opcode>(it->Next()))); 15553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Compute slots for arguments. 15573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < args_slots->length(); ++i) { 15583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (*args_slots)[i] = ComputeSlotForNextArgument(it, data, frame); 15593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 15613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15633ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochVector<SlotRef> SlotRef::ComputeSlotMappingForArguments( 15643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JavaScriptFrame* frame, 15653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int inlined_jsframe_index, 15663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int formal_parameter_count) { 15678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch AssertNoAllocation no_gc; 15688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int deopt_index = AstNode::kNoNumber; 15698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch DeoptimizationInputData* data = 15708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); 15718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch TranslationIterator it(data->TranslationByteArray(), 15728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch data->TranslationIndex(deopt_index)->value()); 15738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 15748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(opcode == Translation::BEGIN); 15753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Next(); // Drop frame count. 15763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframe_count = it.Next(); 15773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch USE(jsframe_count); 15783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(jsframe_count > inlined_jsframe_index); 15793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframes_to_skip = inlined_jsframe_index; 15808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch while (true) { 15818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch opcode = static_cast<Translation::Opcode>(it.Next()); 15823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) { 15833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (jsframes_to_skip == 0) { 15843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Translation::NumberOfOperandsFor(opcode) == 2); 15853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Skip(1); // literal id 15873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int height = it.Next(); 15883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We reached the arguments adaptor frame corresponding to the 15903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // inlined function in question. Number of arguments is height - 1. 15913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Vector<SlotRef> args_slots = 15923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Vector<SlotRef>::New(height - 1); // Minus receiver. 15933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ComputeSlotsForArguments(&args_slots, &it, data, frame); 15943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return args_slots; 15953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (opcode == Translation::JS_FRAME) { 15973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (jsframes_to_skip == 0) { 15983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip over operands to advance to the next opcode. 15993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Skip(Translation::NumberOfOperandsFor(opcode)); 16003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // We reached the frame corresponding to the inlined function 16028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // in question. Process the translation commands for the 16033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // arguments. Number of arguments is equal to the number of 16043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // format parameter count. 16053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Vector<SlotRef> args_slots = 16063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Vector<SlotRef>::New(formal_parameter_count); 16073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ComputeSlotsForArguments(&args_slots, &it, data, frame); 16083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return args_slots; 16098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 16103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jsframes_to_skip--; 16118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 16123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip over operands to advance to the next opcode. 16143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Skip(Translation::NumberOfOperandsFor(opcode)); 16158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 16168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 16178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch UNREACHABLE(); 16183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Vector<SlotRef>(); 16198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 16208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 162169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 16228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 16233ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer, 16243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int frame_index, 16253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_arguments_adaptor, 16263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_construct_stub) { 16273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FrameDescription* output_frame = deoptimizer->output_[frame_index]; 16283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_ = output_frame->GetFunction(); 16293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_construct_stub_ = has_construct_stub; 16303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expression_count_ = output_frame->GetExpressionCount(); 16313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expression_stack_ = new Object*[expression_count_]; 16323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Get the source position using the unoptimized code. 16333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address pc = reinterpret_cast<Address>(output_frame->GetPc()); 16343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = Code::cast(Isolate::Current()->heap()->FindCodeObject(pc)); 16353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch source_position_ = code->SourcePosition(pc); 16363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < expression_count_; i++) { 16383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetExpression(i, output_frame->GetExpression(i)); 16393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 16403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (has_arguments_adaptor) { 16423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch output_frame = deoptimizer->output_[frame_index - 1]; 16433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(output_frame->GetFrameType() == StackFrame::ARGUMENTS_ADAPTOR); 16443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 16453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch parameters_count_ = output_frame->ComputeParametersCount(); 16473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch parameters_ = new Object*[parameters_count_]; 16483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < parameters_count_; i++) { 16493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetParameter(i, output_frame->GetParameter(i)); 16503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 16513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 16523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 16533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 16543fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochDeoptimizedFrameInfo::~DeoptimizedFrameInfo() { 16553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch delete[] expression_stack_; 16563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch delete[] parameters_; 16573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 16583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 16593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { 16613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v->VisitPointer(BitCast<Object**>(&function_)); 16623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v->VisitPointers(parameters_, parameters_ + parameters_count_); 16633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); 16643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 16653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 166669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif // ENABLE_DEBUGGER_SUPPORT 16673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} } // namespace v8::internal 1669