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