deoptimizer.cc revision 086aeeaae12517475c22695a200be45495516549
1b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Copyright 2010 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
42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochLargeObjectChunk* Deoptimizer::eager_deoptimization_entry_code_ = NULL;
43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochLargeObjectChunk* Deoptimizer::lazy_deoptimization_entry_code_ = NULL;
44b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer* Deoptimizer::current_ = NULL;
45b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizingCodeListNode* Deoptimizer::deoptimizing_code_list_ = NULL;
46b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
47b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer* Deoptimizer::New(JSFunction* function,
49b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              BailoutType type,
50b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              unsigned bailout_id,
51b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              Address from,
52b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                              int fp_to_sp_delta) {
53b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Deoptimizer* deoptimizer =
54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      new Deoptimizer(function, type, bailout_id, from, fp_to_sp_delta);
55b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(current_ == NULL);
56b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  current_ = deoptimizer;
57b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return deoptimizer;
58b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
59b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
60b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
61b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer* Deoptimizer::Grab() {
62b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Deoptimizer* result = current_;
63b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(result != NULL);
64b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  result->DeleteFrameDescriptions();
65b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  current_ = NULL;
66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
67b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
69b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
70b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
71b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                int count,
72b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                BailoutType type) {
73b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TableEntryGenerator generator(masm, type, count);
74b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  generator.Generate();
75b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
76b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
77b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
78b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass DeoptimizingVisitor : public OptimizedFunctionVisitor {
79b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
80b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void EnterContext(Context* context) {
81b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (FLAG_trace_deopt) {
82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      PrintF("[deoptimize context: %" V8PRIxPTR "]\n",
83b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch             reinterpret_cast<intptr_t>(context));
84b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
85b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
86b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
87b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void VisitFunction(JSFunction* function) {
88b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Deoptimizer::DeoptimizeFunction(function);
89b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
90b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
91b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void LeaveContext(Context* context) {
92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    context->ClearOptimizedFunctions();
93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DeoptimizeAll() {
98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AssertNoAllocation no_allocation;
99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (FLAG_trace_deopt) {
101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintF("[deoptimize all contexts]\n");
102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizingVisitor visitor;
105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  VisitAllOptimizedFunctions(&visitor);
106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DeoptimizeGlobalObject(JSObject* object) {
110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AssertNoAllocation no_allocation;
111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizingVisitor visitor;
113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  VisitAllOptimizedFunctionsForGlobalObject(object, &visitor);
114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::VisitAllOptimizedFunctionsForContext(
118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Context* context, OptimizedFunctionVisitor* visitor) {
119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AssertNoAllocation no_allocation;
120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(context->IsGlobalContext());
122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  visitor->EnterContext(context);
124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Run through the list of optimized functions and deoptimize them.
125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Object* element = context->OptimizedFunctionsListHead();
126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (!element->IsUndefined()) {
127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSFunction* element_function = JSFunction::cast(element);
128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Get the next link before deoptimizing as deoptimizing will clear the
129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // next link.
130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    element = element_function->next_function_link();
131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    visitor->VisitFunction(element_function);
132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  visitor->LeaveContext(context);
134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::VisitAllOptimizedFunctionsForGlobalObject(
138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSObject* object, OptimizedFunctionVisitor* visitor) {
139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AssertNoAllocation no_allocation;
140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (object->IsJSGlobalProxy()) {
142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Object* proto = object->GetPrototype();
143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(proto->IsJSGlobalObject());
144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    VisitAllOptimizedFunctionsForContext(
145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        GlobalObject::cast(proto)->global_context(), visitor);
146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else if (object->IsGlobalObject()) {
147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    VisitAllOptimizedFunctionsForContext(
148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        GlobalObject::cast(object)->global_context(), visitor);
149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::VisitAllOptimizedFunctions(
154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    OptimizedFunctionVisitor* visitor) {
155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AssertNoAllocation no_allocation;
156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Run through the list of all global contexts and deoptimize.
158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Object* global = Heap::global_contexts_list();
159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (!global->IsUndefined()) {
160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    VisitAllOptimizedFunctionsForGlobalObject(Context::cast(global)->global(),
161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                              visitor);
162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    global = Context::cast(global)->get(Context::NEXT_CONTEXT_LINK);
163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::HandleWeakDeoptimizedCode(
168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    v8::Persistent<v8::Value> obj, void* data) {
169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizingCodeListNode* node =
170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      reinterpret_cast<DeoptimizingCodeListNode*>(data);
171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  RemoveDeoptimizingCode(*node->code());
172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  node = Deoptimizer::deoptimizing_code_list_;
174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (node != NULL) {
175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(node != reinterpret_cast<DeoptimizingCodeListNode*>(data));
176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    node = node->next();
177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  deoptimizer->DoComputeOutputFrames();
184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer::Deoptimizer(JSFunction* function,
188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         BailoutType type,
189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         unsigned bailout_id,
190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         Address from,
191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         int fp_to_sp_delta)
192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    : function_(function),
193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bailout_id_(bailout_id),
194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bailout_type_(type),
195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      from_(from),
196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      fp_to_sp_delta_(fp_to_sp_delta),
197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_count_(0),
198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_(NULL),
199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      integer32_values_(NULL),
200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      double_values_(NULL) {
201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (FLAG_trace_deopt && type != OSR) {
202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintF("**** DEOPT: ");
203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    function->PrintName();
204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           bailout_id,
206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           reinterpret_cast<intptr_t>(from),
207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           fp_to_sp_delta - (2 * kPointerSize));
208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else if (FLAG_trace_osr && type == OSR) {
209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintF("**** OSR: ");
210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    function->PrintName();
211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintF(" at ast id #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           bailout_id,
213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           reinterpret_cast<intptr_t>(from),
214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           fp_to_sp_delta - (2 * kPointerSize));
215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Find the optimized code.
217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (type == EAGER) {
218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(from == NULL);
219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    optimized_code_ = function_->code();
220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else if (type == LAZY) {
221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    optimized_code_ = FindDeoptimizingCodeFromAddress(from);
222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(optimized_code_ != NULL);
223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else if (type == OSR) {
224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // The function has already been optimized and we're transitioning
225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // from the unoptimized shared version to the optimized one in the
226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // function. The return address (from) points to unoptimized code.
227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    optimized_code_ = function_->code();
228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(optimized_code_->kind() == Code::OPTIMIZED_FUNCTION);
229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(!optimized_code_->contains(from));
230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(Heap::allow_allocation(false));
232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned size = ComputeInputFrameSize();
233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  input_ = new(size) FrameDescription(size, function);
234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizer::~Deoptimizer() {
238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(input_ == NULL && output_ == NULL);
239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete[] integer32_values_;
240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete[] double_values_;
241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DeleteFrameDescriptions() {
245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete input_;
246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < output_count_; ++i) {
247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (output_[i] != input_) delete output_[i];
248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  delete[] output_;
250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  input_ = NULL;
251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  output_ = NULL;
252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(!Heap::allow_allocation(true));
253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochAddress Deoptimizer::GetDeoptimizationEntry(int id, BailoutType type) {
257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(id >= 0);
258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (id >= kNumberOfEntries) return NULL;
259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LargeObjectChunk* base = NULL;
260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (type == EAGER) {
261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (eager_deoptimization_entry_code_ == NULL) {
262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      eager_deoptimization_entry_code_ = CreateCode(type);
263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    base = eager_deoptimization_entry_code_;
265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (lazy_deoptimization_entry_code_ == NULL) {
267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      lazy_deoptimization_entry_code_ = CreateCode(type);
268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    base = lazy_deoptimization_entry_code_;
270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return
272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<Address>(base->GetStartAddress()) + (id * table_entry_size_);
273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) {
277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LargeObjectChunk* base = NULL;
278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (type == EAGER) {
279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    base = eager_deoptimization_entry_code_;
280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    base = lazy_deoptimization_entry_code_;
282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (base == NULL ||
284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      addr < base->GetStartAddress() ||
285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      addr >= base->GetStartAddress() +
286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          (kNumberOfEntries * table_entry_size_)) {
287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return kNotDeoptimizationEntry;
288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT_EQ(0,
290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<int>(addr - base->GetStartAddress()) % table_entry_size_);
291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return static_cast<int>(addr - base->GetStartAddress()) / table_entry_size_;
292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::Setup() {
296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Do nothing yet.
297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::TearDown() {
301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (eager_deoptimization_entry_code_ != NULL) {
302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    eager_deoptimization_entry_code_->Free(EXECUTABLE);
303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    eager_deoptimization_entry_code_ = NULL;
304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (lazy_deoptimization_entry_code_ != NULL) {
306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    lazy_deoptimization_entry_code_->Free(EXECUTABLE);
307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    lazy_deoptimization_entry_code_ = NULL;
308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3129fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockint Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
3139fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                               unsigned id,
3149fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                               SharedFunctionInfo* shared) {
315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // TODO(kasperl): For now, we do a simple linear search for the PC
316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // offset associated with the given node id. This should probably be
317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // changed to a binary search.
318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = data->DeoptPoints();
319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Smi* smi_id = Smi::FromInt(id);
320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < length; i++) {
321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (data->AstId(i) == smi_id) {
322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return data->PcAndState(i)->value();
323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  PrintF("[couldn't find pc offset for node=%u]\n", id);
326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  PrintF("[method: %s]\n", *shared->DebugName()->ToCString());
327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Print the source code if available.
328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HeapStringAllocator string_allocator;
329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  StringStream stream(&string_allocator);
330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  shared->SourceCodePrint(&stream, -1);
331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  PrintF("[source:\n%s\n]", *stream.ToCString());
332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  UNREACHABLE();
334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return -1;
335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint Deoptimizer::GetDeoptimizedCodeCount() {
339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = 0;
340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizingCodeListNode* node = Deoptimizer::deoptimizing_code_list_;
341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (node != NULL) {
342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    length++;
343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    node = node->next();
344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return length;
346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DoComputeOutputFrames() {
350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (bailout_type_ == OSR) {
351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    DoComputeOsrOutputFrame();
352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return;
353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Print some helpful diagnostic information.
356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int64_t start = OS::Ticks();
357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (FLAG_trace_deopt) {
358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ",
359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           (bailout_type_ == LAZY ? " (lazy)" : ""),
360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           reinterpret_cast<intptr_t>(function_));
361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    function_->PrintName();
362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintF(" @%d]\n", bailout_id_);
363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Determine basic deoptimization information.  The optimized frame is
366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // described by the input data.
367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizationInputData* input_data =
368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      DeoptimizationInputData::cast(optimized_code_->deoptimization_data());
369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned node_id = input_data->AstId(bailout_id_)->value();
370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ByteArray* translations = input_data->TranslationByteArray();
371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned translation_index =
372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      input_data->TranslationIndex(bailout_id_)->value();
373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Do the input frame to output frame(s) translation.
375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TranslationIterator iterator(translations, translation_index);
376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Translation::Opcode opcode =
377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<Translation::Opcode>(iterator.Next());
378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(Translation::BEGIN == opcode);
379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  USE(opcode);
380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Read the number of output frames and allocate an array for their
381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // descriptions.
382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int count = iterator.Next();
383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(output_ == NULL);
384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  output_ = new FrameDescription*[count];
385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Per-frame lists of untagged and unboxed int32 and double values.
386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  integer32_values_ = new List<ValueDescriptionInteger32>[count];
387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  double_values_ = new List<ValueDescriptionDouble>[count];
388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < count; ++i) {
389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    output_[i] = NULL;
390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    integer32_values_[i].Initialize(0);
391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    double_values_[i].Initialize(0);
392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  output_count_ = count;
394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Translate each output frame.
396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < count; ++i) {
397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    DoComputeFrame(&iterator, i);
398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Print some helpful diagnostic information.
401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (FLAG_trace_deopt) {
402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    double ms = static_cast<double>(OS::Ticks() - start) / 1000;
403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int index = output_count_ - 1;  // Index of the topmost frame.
404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSFunction* function = output_[index]->GetFunction();
405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ",
406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           reinterpret_cast<intptr_t>(function));
407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    function->PrintName();
408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintF(" => node=%u, pc=0x%08" V8PRIxPTR ", state=%s, took %0.3f ms]\n",
409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           node_id,
410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           output_[index]->GetPc(),
411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           FullCodeGenerator::State2String(
412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               static_cast<FullCodeGenerator::State>(
413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                   output_[index]->GetState()->value())),
414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch           ms);
415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::InsertHeapNumberValues(int index, JavaScriptFrame* frame) {
420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // We need to adjust the stack index by one for the top-most frame.
421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int extra_slot_count = (index == output_count() - 1) ? 1 : 0;
422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  List<ValueDescriptionInteger32>* ints = &integer32_values_[index];
423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < ints->length(); i++) {
424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ValueDescriptionInteger32 value = ints->at(i);
425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    double val = static_cast<double>(value.int32_value());
426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    InsertHeapNumberValue(frame, value.stack_index(), val, extra_slot_count);
427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Iterate over double values and convert them to a heap number.
430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  List<ValueDescriptionDouble>* doubles = &double_values_[index];
431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < doubles->length(); ++i) {
432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ValueDescriptionDouble value = doubles->at(i);
433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    InsertHeapNumberValue(frame, value.stack_index(), value.double_value(),
434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          extra_slot_count);
435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::InsertHeapNumberValue(JavaScriptFrame* frame,
440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                        int stack_index,
441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                        double val,
442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                        int extra_slot_count) {
443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Add one to the TOS index to take the 'state' pushed before jumping
444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // to the stub that calls Runtime::NotifyDeoptimized into account.
445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int tos_index = stack_index + extra_slot_count;
446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int index = (frame->ComputeExpressionsCount() - 1) - tos_index;
447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (FLAG_trace_deopt) PrintF("Allocating a new heap number: %e\n", val);
448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<Object> num = Factory::NewNumber(val);
449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  frame->SetExpression(index, *num);
450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                     int frame_index,
455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                     unsigned output_offset) {
456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  disasm::NameConverter converter;
457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // A GC-safe temporary placeholder that we can put in the output frame.
458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0));
459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Ignore commands marked as duplicate and act on the first non-duplicate.
461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Translation::Opcode opcode =
462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (opcode == Translation::DUPLICATE) {
464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    opcode = static_cast<Translation::Opcode>(iterator->Next());
465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    iterator->Skip(Translation::NumberOfOperandsFor(opcode));
466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    opcode = static_cast<Translation::Opcode>(iterator->Next());
467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  switch (opcode) {
470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::BEGIN:
471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::FRAME:
472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::DUPLICATE:
473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      UNREACHABLE();
474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::REGISTER: {
477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int input_reg = iterator->Next();
478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      intptr_t input_value = input_->GetRegister(input_reg);
479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_deopt) {
480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF(
481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s\n",
482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            output_[frame_index]->GetTop() + output_offset,
483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            output_offset,
484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            input_value,
485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            converter.NameOfCPURegister(input_reg));
486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_[frame_index]->SetFrameSlot(output_offset, input_value);
488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::INT32_REGISTER: {
492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int input_reg = iterator->Next();
493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      intptr_t value = input_->GetRegister(input_reg);
494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bool is_smi = Smi::IsValid(value);
495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned output_index = output_offset / kPointerSize;
496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_deopt) {
497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF(
498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            "    0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            output_[frame_index]->GetTop() + output_offset,
500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            output_offset,
501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            value,
502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            converter.NameOfCPURegister(input_reg),
503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            is_smi ? "smi" : "heap number");
504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (is_smi) {
506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        intptr_t tagged_value =
507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      } else {
510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        // We save the untagged value on the side and store a GC-safe
511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        // temporary placeholder in the frame.
512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        AddInteger32Value(frame_index,
513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          output_index,
514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          static_cast<int32_t>(value));
515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::DOUBLE_REGISTER: {
521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int input_reg = iterator->Next();
522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      double value = input_->GetDoubleRegister(input_reg);
523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned output_index = output_offset / kPointerSize;
524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_deopt) {
525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n",
526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_[frame_index]->GetTop() + output_offset,
527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset,
528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               value,
529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               DoubleRegister::AllocationIndexToString(input_reg));
530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // We save the untagged value on the side and store a GC-safe
532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // temporary placeholder in the frame.
533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      AddDoubleValue(frame_index, output_index, value);
534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::STACK_SLOT: {
539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int input_slot_index = iterator->Next();
540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned input_offset =
541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          input_->GetOffsetFromSlotIndex(this, input_slot_index);
542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      intptr_t input_value = input_->GetFrameSlot(input_offset);
543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_deopt) {
544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    0x%08" V8PRIxPTR ": ",
545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_[frame_index]->GetTop() + output_offset);
546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d]\n",
547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset,
548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               input_value,
549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               input_offset);
550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_[frame_index]->SetFrameSlot(output_offset, input_value);
552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::INT32_STACK_SLOT: {
556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int input_slot_index = iterator->Next();
557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned input_offset =
558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          input_->GetOffsetFromSlotIndex(this, input_slot_index);
559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      intptr_t value = input_->GetFrameSlot(input_offset);
560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      bool is_smi = Smi::IsValid(value);
561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned output_index = output_offset / kPointerSize;
562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_deopt) {
563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    0x%08" V8PRIxPTR ": ",
564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_[frame_index]->GetTop() + output_offset);
565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("[top + %d] <- %" V8PRIdPTR " ; [esp + %d] (%s)\n",
566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset,
567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               value,
568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               input_offset,
569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               is_smi ? "smi" : "heap number");
570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (is_smi) {
572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        intptr_t tagged_value =
573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      } else {
576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        // We save the untagged value on the side and store a GC-safe
577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        // temporary placeholder in the frame.
578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        AddInteger32Value(frame_index,
579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          output_index,
580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          static_cast<int32_t>(value));
581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::DOUBLE_STACK_SLOT: {
587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int input_slot_index = iterator->Next();
588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned input_offset =
589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          input_->GetOffsetFromSlotIndex(this, input_slot_index);
590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      double value = input_->GetDoubleFrameSlot(input_offset);
591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned output_index = output_offset / kPointerSize;
592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_deopt) {
593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- %e ; [esp + %d]\n",
594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_[frame_index]->GetTop() + output_offset,
595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset,
596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               value,
597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               input_offset);
598b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // We save the untagged value on the side and store a GC-safe
600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // temporary placeholder in the frame.
601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      AddDoubleValue(frame_index, output_index, value);
602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::LITERAL: {
607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      Object* literal = ComputeLiteral(iterator->Next());
608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_deopt) {
609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- ",
610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_[frame_index]->GetTop() + output_offset,
611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset);
612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        literal->ShortPrint();
613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF(" ; literal\n");
614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      intptr_t value = reinterpret_cast<intptr_t>(literal);
616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_[frame_index]->SetFrameSlot(output_offset, value);
617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::ARGUMENTS_OBJECT: {
621086aeeaae12517475c22695a200be45495516549Ben Murdoch      // Use the arguments marker value as a sentinel and fill in the arguments
622086aeeaae12517475c22695a200be45495516549Ben Murdoch      // object after the deoptimized frame is built.
623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      ASSERT(frame_index == 0);  // Only supported for first frame.
624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_deopt) {
625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- ",
626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_[frame_index]->GetTop() + output_offset,
627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset);
628086aeeaae12517475c22695a200be45495516549Ben Murdoch        Heap::arguments_marker()->ShortPrint();
629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF(" ; arguments object\n");
630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
631086aeeaae12517475c22695a200be45495516549Ben Murdoch      intptr_t value = reinterpret_cast<intptr_t>(Heap::arguments_marker());
632b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output_[frame_index]->SetFrameSlot(output_offset, value);
633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
638b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
639b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
640b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                        int* input_offset) {
641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  disasm::NameConverter converter;
642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FrameDescription* output = output_[0];
643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The input values are all part of the unoptimized frame so they
645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // are all tagged pointers.
646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uintptr_t input_value = input_->GetFrameSlot(*input_offset);
647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Object* input_object = reinterpret_cast<Object*>(input_value);
648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Translation::Opcode opcode =
650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<Translation::Opcode>(iterator->Next());
651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool duplicate = (opcode == Translation::DUPLICATE);
652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (duplicate) {
653b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    opcode = static_cast<Translation::Opcode>(iterator->Next());
654b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  switch (opcode) {
657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::BEGIN:
658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::FRAME:
659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::DUPLICATE:
660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      UNREACHABLE();  // Malformed input.
661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch       return false;
662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch     case Translation::REGISTER: {
664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch       int output_reg = iterator->Next();
665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch       if (FLAG_trace_osr) {
666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch         PrintF("    %s <- 0x%08" V8PRIxPTR " ; [esp + %d]\n",
667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                converter.NameOfCPURegister(output_reg),
668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                input_value,
669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                *input_offset);
670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch       }
671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch       output->SetRegister(output_reg, input_value);
672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch       break;
673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch     }
674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::INT32_REGISTER: {
676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Abort OSR if we don't have a number.
677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (!input_object->IsNumber()) return false;
678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int output_reg = iterator->Next();
680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int int32_value = input_object->IsSmi()
681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          ? Smi::cast(input_object)->value()
682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          : FastD2I(input_object->Number());
683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Abort the translation if the conversion lost information.
684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (!input_object->IsSmi() &&
685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          FastI2D(int32_value) != input_object->Number()) {
686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        if (FLAG_trace_osr) {
687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          PrintF("**** %g could not be converted to int32 ****\n",
688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                 input_object->Number());
689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        }
690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        return false;
691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_osr) {
693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    %s <- %d (int32) ; [esp + %d]\n",
694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               converter.NameOfCPURegister(output_reg),
695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               int32_value,
696b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               *input_offset);
697b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
698b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output->SetRegister(output_reg, int32_value);
699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      break;
700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
702b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::DOUBLE_REGISTER: {
703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Abort OSR if we don't have a number.
704b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (!input_object->IsNumber()) return false;
705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int output_reg = iterator->Next();
707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      double double_value = input_object->Number();
708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_osr) {
709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    %s <- %g (double) ; [esp + %d]\n",
710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               DoubleRegister::AllocationIndexToString(output_reg),
711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               double_value,
712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               *input_offset);
713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output->SetDoubleRegister(output_reg, double_value);
715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      break;
716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::STACK_SLOT: {
719b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int output_index = iterator->Next();
720b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned output_offset =
721b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          output->GetOffsetFromSlotIndex(this, output_index);
722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_osr) {
723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    [esp + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d]\n",
724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset,
725b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               input_value,
726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               *input_offset);
727b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
728b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output->SetFrameSlot(output_offset, input_value);
729b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      break;
730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::INT32_STACK_SLOT: {
733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Abort OSR if we don't have a number.
734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (!input_object->IsNumber()) return false;
735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int output_index = iterator->Next();
737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned output_offset =
738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          output->GetOffsetFromSlotIndex(this, output_index);
739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int int32_value = input_object->IsSmi()
740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          ? Smi::cast(input_object)->value()
741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          : DoubleToInt32(input_object->Number());
742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Abort the translation if the conversion lost information.
743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (!input_object->IsSmi() &&
744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          FastI2D(int32_value) != input_object->Number()) {
745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        if (FLAG_trace_osr) {
746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          PrintF("**** %g could not be converted to int32 ****\n",
747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                 input_object->Number());
748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        }
749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        return false;
750b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_osr) {
752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    [esp + %d] <- %d (int32) ; [esp + %d]\n",
753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset,
754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               int32_value,
755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               *input_offset);
756b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
757b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output->SetFrameSlot(output_offset, int32_value);
758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      break;
759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::DOUBLE_STACK_SLOT: {
762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static const int kLowerOffset = 0 * kPointerSize;
763b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static const int kUpperOffset = 1 * kPointerSize;
764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
765b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Abort OSR if we don't have a number.
766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (!input_object->IsNumber()) return false;
767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int output_index = iterator->Next();
769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      unsigned output_offset =
770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          output->GetOffsetFromSlotIndex(this, output_index);
771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      double double_value = input_object->Number();
772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      uint64_t int_value = BitCast<uint64_t, double>(double_value);
773b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int32_t lower = static_cast<int32_t>(int_value);
774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int32_t upper = static_cast<int32_t>(int_value >> kBitsPerInt);
775b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (FLAG_trace_osr) {
776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    [esp + %d] <- 0x%08x (upper bits of %g) ; [esp + %d]\n",
777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset + kUpperOffset,
778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               upper,
779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               double_value,
780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               *input_offset);
781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        PrintF("    [esp + %d] <- 0x%08x (lower bits of %g) ; [esp + %d]\n",
782b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               output_offset + kLowerOffset,
783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               lower,
784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               double_value,
785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               *input_offset);
786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output->SetFrameSlot(output_offset + kLowerOffset, lower);
788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      output->SetFrameSlot(output_offset + kUpperOffset, upper);
789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      break;
790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::LITERAL: {
793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Just ignore non-materialized literals.
794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      iterator->Next();
795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      break;
796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
797b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
798b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case Translation::ARGUMENTS_OBJECT: {
799b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Optimized code assumes that the argument object has not been
800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // materialized and so bypasses it when doing arguments access.
801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // We should have bailed out before starting the frame
802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // translation.
803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      UNREACHABLE();
804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return false;
805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
806b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
807b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (!duplicate) *input_offset -= kPointerSize;
809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return true;
810b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
812b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
813b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned Deoptimizer::ComputeInputFrameSize() const {
814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned fixed_size = ComputeFixedSize(function_);
815b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The fp-to-sp delta already takes the context and the function
816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // into account so we have to avoid double counting them (-2).
817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize);
818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (bailout_type_ == OSR) {
820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // TODO(kasperl): It would be nice if we could verify that the
821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // size matches with the stack height we can compute based on the
822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // environment at the OSR entry. The code for that his built into
823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // the DoComputeOsrOutputFrame function for now.
824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    unsigned stack_slots = optimized_code_->stack_slots();
826b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    unsigned outgoing_size = ComputeOutgoingArgumentSize();
827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);
828b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
834b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const {
835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The fixed part of the frame consists of the return address, frame
836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // pointer, function, context, and all the incoming arguments.
837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const unsigned kFixedSlotSize = 4 * kPointerSize;
838b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return ComputeIncomingArgumentSize(function) + kFixedSlotSize;
839b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
840b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const {
843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The incoming arguments is the values for formal parameters and
844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // the receiver. Every slot contains a pointer.
845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned arguments = function->shared()->formal_parameter_count() + 1;
846b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return arguments * kPointerSize;
847b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
848b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
849b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned Deoptimizer::ComputeOutgoingArgumentSize() const {
851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizationInputData* data = DeoptimizationInputData::cast(
852b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      optimized_code_->deoptimization_data());
853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned height = data->ArgumentsStackHeight(bailout_id_)->value();
854b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return height * kPointerSize;
855b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
858b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochObject* Deoptimizer::ComputeLiteral(int index) const {
859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizationInputData* data = DeoptimizationInputData::cast(
860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      optimized_code_->deoptimization_data());
861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FixedArray* literals = data->LiteralArray();
862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return literals->get(index);
863b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
865b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::AddInteger32Value(int frame_index,
867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                    int slot_index,
868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                    int32_t value) {
869b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ValueDescriptionInteger32 value_desc(slot_index, value);
870b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  integer32_values_[frame_index].Add(value_desc);
871b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
872b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
873b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
874b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::AddDoubleValue(int frame_index,
875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                 int slot_index,
876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                 double value) {
877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ValueDescriptionDouble value_desc(slot_index, value);
878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  double_values_[frame_index].Add(value_desc);
879b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
880b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
881b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochLargeObjectChunk* Deoptimizer::CreateCode(BailoutType type) {
883b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // We cannot run this if the serializer is enabled because this will
884b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // cause us to emit relocation information for the external
885b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // references. This is fine because the deoptimizer's code section
886b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // isn't meant to be serialized at all.
887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(!Serializer::enabled());
888b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool old_debug_code = FLAG_debug_code;
889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FLAG_debug_code = false;
890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  MacroAssembler masm(NULL, 16 * KB);
892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type);
893b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CodeDesc desc;
894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  masm.GetCode(&desc);
895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(desc.reloc_size == 0);
896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LargeObjectChunk* chunk = LargeObjectChunk::New(desc.instr_size, EXECUTABLE);
898b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size);
899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size);
900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FLAG_debug_code = old_debug_code;
901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return chunk;
902b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
903b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
905b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochCode* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) {
906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizingCodeListNode* node = Deoptimizer::deoptimizing_code_list_;
907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (node != NULL) {
908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (node->code()->contains(addr)) return *node->code();
909b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    node = node->next();
910b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
911b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return NULL;
912b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
913b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
914b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
915b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::RemoveDeoptimizingCode(Code* code) {
916b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(deoptimizing_code_list_ != NULL);
917b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Run through the code objects to find this one and remove it.
918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizingCodeListNode* prev = NULL;
919b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DeoptimizingCodeListNode* current = deoptimizing_code_list_;
920b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (current != NULL) {
921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (*current->code() == code) {
922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Unlink from list. If prev is NULL we are looking at the first element.
923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (prev == NULL) {
924b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        deoptimizing_code_list_ = current->next();
925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      } else {
926b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        prev->set_next(current->next());
927b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
928b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      delete current;
929b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return;
930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
931b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Move to next in list.
932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    prev = current;
933b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    current = current->next();
934b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
935b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Deoptimizing code is removed through weak callback. Each object is expected
936b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // to be removed once and only once.
937b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  UNREACHABLE();
938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
940b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochFrameDescription::FrameDescription(uint32_t frame_size,
942b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                   JSFunction* function)
943b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    : frame_size_(frame_size),
944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      function_(function),
945b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      top_(kZapUint32),
946b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      pc_(kZapUint32),
947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      fp_(kZapUint32) {
948b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Zap all the registers.
949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int r = 0; r < Register::kNumRegisters; r++) {
950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetRegister(r, kZapUint32);
951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Zap all the slots.
954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (unsigned o = 0; o < frame_size; o += kPointerSize) {
955b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFrameSlot(o, kZapUint32);
956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
957b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
958b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned FrameDescription::GetOffsetFromSlotIndex(Deoptimizer* deoptimizer,
961b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                  int slot_index) {
962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (slot_index >= 0) {
963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Local or spill slots. Skip the fixed part of the frame
964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // including all arguments.
965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    unsigned base = static_cast<unsigned>(
966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        GetFrameSize() - deoptimizer->ComputeFixedSize(GetFunction()));
967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return base - ((slot_index + 1) * kPointerSize);
968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
969b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Incoming parameter.
970b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    unsigned base = static_cast<unsigned>(GetFrameSize() -
971b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        deoptimizer->ComputeIncomingArgumentSize(GetFunction()));
972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return base - ((slot_index + 1) * kPointerSize);
973b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
975b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
977b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid TranslationBuffer::Add(int32_t value) {
978b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Encode the sign bit in the least significant bit.
979b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_negative = (value < 0);
980b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t bits = ((is_negative ? -value : value) << 1) |
981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<int32_t>(is_negative);
982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Encode the individual bytes using the least significant bit of
983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // each byte to indicate whether or not more bytes follow.
984b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  do {
985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uint32_t next = bits >> 7;
986b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    contents_.Add(((bits << 1) & 0xFF) | (next != 0));
987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bits = next;
988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } while (bits != 0);
989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
991b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
992b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint32_t TranslationIterator::Next() {
993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(HasNext());
994b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Run through the bytes until we reach one with a least significant
995b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // bit of zero (marks the end).
996b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t bits = 0;
997b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; true; i += 7) {
998b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uint8_t next = buffer_->get(index_++);
999b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bits |= (next >> 1) << i;
1000b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if ((next & 1) == 0) break;
1001b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1002b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The bits encode the sign in the least significant bit.
1003b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_negative = (bits & 1) == 1;
1004b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t result = bits >> 1;
1005b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return is_negative ? -result : result;
1006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1007b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1008b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHandle<ByteArray> TranslationBuffer::CreateByteArray() {
1010b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length = contents_.length();
1011b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<ByteArray> result = Factory::NewByteArray(length, TENURED);
1012b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length);
1013b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
1014b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1015b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1016b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1017b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::BeginFrame(int node_id, int literal_id, unsigned height) {
1018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(FRAME);
1019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(node_id);
1020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(literal_id);
1021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(height);
1022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreRegister(Register reg) {
1026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(REGISTER);
1027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(reg.code());
1028b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1030b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32Register(Register reg) {
1032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(INT32_REGISTER);
1033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(reg.code());
1034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreDoubleRegister(DoubleRegister reg) {
1038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(DOUBLE_REGISTER);
1039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(DoubleRegister::ToAllocationIndex(reg));
1040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1042b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1043b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreStackSlot(int index) {
1044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(STACK_SLOT);
1045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(index);
1046b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1047b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1048b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1049b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreInt32StackSlot(int index) {
1050b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(INT32_STACK_SLOT);
1051b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(index);
1052b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1054b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreDoubleStackSlot(int index) {
1056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(DOUBLE_STACK_SLOT);
1057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(index);
1058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1061b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreLiteral(int literal_id) {
1062b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(LITERAL);
1063b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(literal_id);
1064b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1065b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1066b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1067b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::StoreArgumentsObject() {
1068b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(ARGUMENTS_OBJECT);
1069b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1070b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1071b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Translation::MarkDuplicate() {
1073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  buffer_->Add(DUPLICATE);
1074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1075b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1076b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1077b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint Translation::NumberOfOperandsFor(Opcode opcode) {
1078b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  switch (opcode) {
1079b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case ARGUMENTS_OBJECT:
1080b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DUPLICATE:
1081b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return 0;
1082b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case BEGIN:
1083b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case REGISTER:
1084b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_REGISTER:
1085b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_REGISTER:
1086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case STACK_SLOT:
1087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_STACK_SLOT:
1088b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_STACK_SLOT:
1089b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case LITERAL:
1090b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return 1;
1091b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case FRAME:
1092b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return 3;
1093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1094b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  UNREACHABLE();
1095b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return -1;
1096b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1097b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
1100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* Translation::StringFor(Opcode opcode) {
1102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  switch (opcode) {
1103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case BEGIN:
1104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "BEGIN";
1105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case FRAME:
1106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "FRAME";
1107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case REGISTER:
1108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "REGISTER";
1109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_REGISTER:
1110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "INT32_REGISTER";
1111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_REGISTER:
1112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "DOUBLE_REGISTER";
1113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case STACK_SLOT:
1114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "STACK_SLOT";
1115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case INT32_STACK_SLOT:
1116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "INT32_STACK_SLOT";
1117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DOUBLE_STACK_SLOT:
1118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "DOUBLE_STACK_SLOT";
1119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case LITERAL:
1120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "LITERAL";
1121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case ARGUMENTS_OBJECT:
1122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "ARGUMENTS_OBJECT";
1123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    case DUPLICATE:
1124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      return "DUPLICATE";
1125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  UNREACHABLE();
1127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return "";
1128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
1131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) {
1134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Globalize the code object and make it weak.
1135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  code_ = Handle<Code>::cast((GlobalHandles::Create(code)));
1136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(code_.location()),
1137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          this,
1138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                          Deoptimizer::HandleWeakDeoptimizedCode);
1139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizingCodeListNode::~DeoptimizingCodeListNode() {
1143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  GlobalHandles::Destroy(reinterpret_cast<Object**>(code_.location()));
1144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} }  // namespace v8::internal
1148