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