13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Redistribution and use in source and binary forms, with or without 3b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// modification, are permitted provided that the following conditions are 4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// met: 5b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions of source code must retain the above copyright 7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// notice, this list of conditions and the following disclaimer. 8b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions in binary form must reproduce the above 9b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// copyright notice, this list of conditions and the following 10b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// disclaimer in the documentation and/or other materials provided 11b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// with the distribution. 12b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Neither the name of Google Inc. nor the names of its 13b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// contributors may be used to endorse or promote products derived 14b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// from this software without specific prior written permission. 15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifndef V8_DEOPTIMIZER_H_ 29b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define V8_DEOPTIMIZER_H_ 30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "v8.h" 32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 33257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h" 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "macro-assembler.h" 35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "zone-inl.h" 36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 37b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 { 39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal { 40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass FrameDescription; 42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TranslationIterator; 43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass DeoptimizingCodeListNode; 443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass DeoptimizedFrameInfo; 45b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochclass HeapNumberMaterializationDescriptor BASE_EMBEDDED { 47b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HeapNumberMaterializationDescriptor(Address slot_address, double val) 498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : slot_address_(slot_address), val_(val) { } 50b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address slot_address() const { return slot_address_; } 528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double value() const { return val_; } 53b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address slot_address_; 568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double val_; 57b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 58b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 59b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 60b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass OptimizedFunctionVisitor BASE_EMBEDDED { 61b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 62b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual ~OptimizedFunctionVisitor() {} 63b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 64b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Function which is called before iteration of any optimized functions 65b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // from given global context. 66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void EnterContext(Context* context) = 0; 67b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void VisitFunction(JSFunction* function) = 0; 69b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 70b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Function which is called after iteration of all optimized functions 71b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // from given global context. 72b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void LeaveContext(Context* context) = 0; 73b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 74b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 75b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Deoptimizer; 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass DeoptimizerData { 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 8144f0eee88ff00398ff7f715fab053374d808c90dSteve Block DeoptimizerData(); 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ~DeoptimizerData(); 8344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void Iterate(ObjectVisitor* v); 863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk* eager_deoptimization_entry_code_; 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk* lazy_deoptimization_entry_code_; 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Deoptimizer* current_; 9244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DeoptimizedFrameInfo* deoptimized_frame_info_; 953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // List of deoptimized code which still have references from active stack 9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // frames. These code objects are needed by the deoptimizer when deoptimizing 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // a frame for which the code object for the function function has been 10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // changed from the code present when deoptimizing was done. 10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block DeoptimizingCodeListNode* deoptimizing_code_list_; 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block friend class Deoptimizer; 10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block DISALLOW_COPY_AND_ASSIGN(DeoptimizerData); 10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass Deoptimizer : public Malloced { 110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum BailoutType { 112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EAGER, 113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LAZY, 1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch OSR, 1153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // This last bailout type is not really a bailout, but used by the 1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // debugger to deoptimize stack frames to allow inspection. 1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DEBUGGER 118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int output_count() const { return output_count_; } 121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Number of created JS frames. Not all created frames are necessarily JS. 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframe_count() const { return jsframe_count_; } 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Deoptimizer* New(JSFunction* function, 126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType type, 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned bailout_id, 128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address from, 12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block int fp_to_sp_delta, 13044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate); 13144f0eee88ff00398ff7f715fab053374d808c90dSteve Block static Deoptimizer* Grab(Isolate* isolate); 13244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The returned object with information on the optimized frame needs to be 1353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // freed before another one can be generated. 1363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame, 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframe_index, 1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Isolate* isolate); 1393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info, 1403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Isolate* isolate); 1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 1423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Makes sure that there is enough room in the relocation 14444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // information of a code object to perform lazy deoptimization 14544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // patching. If there is not enough room a new relocation 14644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // information object is allocated and comments are added until it 14744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // is big enough. 14844f0eee88ff00398ff7f715fab053374d808c90dSteve Block static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code); 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Deoptimize the function now. Its current optimized code will never be run 151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // again and any activations of the optimized code will get deoptimized when 152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // execution returns. 153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void DeoptimizeFunction(JSFunction* function); 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Deoptimize all functions in the heap. 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void DeoptimizeAll(); 157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void DeoptimizeGlobalObject(JSObject* object); 159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void VisitAllOptimizedFunctionsForContext( 161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Context* context, OptimizedFunctionVisitor* visitor); 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void VisitAllOptimizedFunctionsForGlobalObject( 164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSObject* object, OptimizedFunctionVisitor* visitor); 165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor* visitor); 167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The size in bytes of the code required at a lazy deopt patch site. 1691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static int patch_size(); 1701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Patch all stack guard checks in the unoptimized code to 1721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // unconditionally call replacement_code. 1731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void PatchStackCheckCode(Code* unoptimized_code, 1741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 1751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code); 1761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Patch stack guard check at instruction before pc_after in 1781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // the unoptimized code to unconditionally call replacement_code. 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void PatchStackCheckCodeAt(Code* unoptimized_code, 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address pc_after, 1811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 1821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code); 1831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Change all patched stack guard checks in the unoptimized code 1851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // back to a normal stack guard check. 1861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void RevertStackCheckCode(Code* unoptimized_code, 1871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 1881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code); 1891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Change all patched stack guard checks in the unoptimized code 1911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // back to a normal stack guard check. 1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void RevertStackCheckCodeAt(Code* unoptimized_code, 1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address pc_after, 1941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 1951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code); 196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ~Deoptimizer(); 198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void MaterializeHeapNumbers(); 2003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 2013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void MaterializeHeapNumbersForDebuggerInspectableFrame( 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address parameters_top, 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t parameters_size, 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address expressions_top, 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t expressions_size, 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizedFrameInfo* info); 2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static void ComputeOutputFrames(Deoptimizer* deoptimizer); 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Address GetDeoptimizationEntry(int id, BailoutType type); 212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int GetDeoptimizationId(Address addr, BailoutType type); 2139fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block static int GetOutputInfo(DeoptimizationOutputData* data, 2149fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block unsigned node_id, 2159fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block SharedFunctionInfo* shared); 216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Code generation support. 218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int input_offset() { return OFFSET_OF(Deoptimizer, input_); } 219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int output_count_offset() { 220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(Deoptimizer, output_count_); 221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int output_offset() { return OFFSET_OF(Deoptimizer, output_); } 223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 22444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static int GetDeoptimizedCodeCount(Isolate* isolate); 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kNotDeoptimizationEntry = -1; 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Generators for the deoptimization entry code. 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch class EntryGenerator BASE_EMBEDDED { 230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EntryGenerator(MacroAssembler* masm, BailoutType type) 232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : masm_(masm), type_(type) { } 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual ~EntryGenerator() { } 234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Generate(); 236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MacroAssembler* masm() const { return masm_; } 239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType type() const { return type_; } 240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GeneratePrologue() { } 242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MacroAssembler* masm_; 245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Deoptimizer::BailoutType type_; 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch class TableEntryGenerator : public EntryGenerator { 249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TableEntryGenerator(MacroAssembler* masm, BailoutType type, int count) 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : EntryGenerator(masm, type), count_(count) { } 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GeneratePrologue(); 255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int count() const { return count_; } 258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int count_; 260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int ConvertJSFrameIndexToFrameIndex(int jsframe_index); 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kNumberOfEntries = 16384; 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Deoptimizer(Isolate* isolate, 26844f0eee88ff00398ff7f715fab053374d808c90dSteve Block JSFunction* function, 269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType type, 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned bailout_id, 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address from, 2723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int fp_to_sp_delta, 2733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code* optimized_code); 274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DeleteFrameDescriptions(); 275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoComputeOutputFrames(); 277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoComputeOsrOutputFrame(); 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoComputeJSFrame(TranslationIterator* iterator, int frame_index); 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int frame_index); 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoComputeConstructStubFrame(TranslationIterator* iterator, 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int frame_index); 283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoTranslateCommand(TranslationIterator* iterator, 284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int frame_index, 285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned output_offset); 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Translate a command for OSR. Updates the input offset to be used for 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the next command. Returns false if translation of the command failed 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // (e.g., a number conversion failed) and may or may not have updated the 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // input offset. 290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool DoOsrTranslateCommand(TranslationIterator* iterator, 291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int* input_offset); 292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned ComputeInputFrameSize() const; 294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned ComputeFixedSize(JSFunction* function) const; 295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned ComputeIncomingArgumentSize(JSFunction* function) const; 297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned ComputeOutgoingArgumentSize() const; 298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* ComputeLiteral(int index) const; 300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void AddDoubleValue(intptr_t slot_address, double value); 302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MemoryChunk* CreateCode(BailoutType type); 304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void GenerateDeoptimizationEntries( 305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MacroAssembler* masm, int count, BailoutType type); 306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Weak handle callback for deoptimizing code objects. 308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void HandleWeakDeoptimizedCode( 309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Persistent<v8::Value> obj, void* data); 310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Code* FindDeoptimizingCodeFromAddress(Address addr); 311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void RemoveDeoptimizingCode(Code* code); 312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Fill the input from from a JavaScript frame. This is used when 3143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // the debugger needs to inspect an optimized frame. For normal 3153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // deoptimizations the input frame is filled in generated code. 3163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void FillInputFrame(Address tos, JavaScriptFrame* frame); 3173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function_; 320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* optimized_code_; 321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned bailout_id_; 322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType bailout_type_; 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address from_; 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int fp_to_sp_delta_; 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Input frame description. 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameDescription* input_; 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Number of output frames. 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int output_count_; 3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Number of output js frames. 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframe_count_; 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Array of output frame descriptions. 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameDescription** output_; 334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_; 336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 33769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static const int table_entry_size_; 338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class FrameDescription; 340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class DeoptimizingCodeListNode; 3413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch friend class DeoptimizedFrameInfo; 342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass FrameDescription { 346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameDescription(uint32_t frame_size, 348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function); 349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void* operator new(size_t size, uint32_t frame_size) { 35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Subtracts kPointerSize, as the member frame_content_ already supplies 35244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // the first element of the area to store the frame. 35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return malloc(size + frame_size - kPointerSize); 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 35669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void operator delete(void* pointer, uint32_t frame_size) { 35769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch free(pointer); 35869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 35969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void operator delete(void* description) { 361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch free(description); 362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t GetFrameSize() const { 3653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_); 3663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return static_cast<uint32_t>(frame_size_); 3673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* GetFunction() const { return function_; } 370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned GetOffsetFromSlotIndex(int slot_index); 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetFrameSlot(unsigned offset) { 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return *GetFrameSlotPointer(offset); 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double GetDoubleFrameSlot(unsigned offset) { 3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t* ptr = GetFrameSlotPointer(offset); 3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if V8_TARGET_ARCH_MIPS 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Prevent gcc from using load-double (mips ldc1) on (possibly) 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // non-64-bit aligned double. Uses two lwc1 instructions. 3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch union conversion { 3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double d; 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t u[2]; 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } c; 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch c.u[0] = *reinterpret_cast<uint32_t*>(ptr); 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch c.u[1] = *(reinterpret_cast<uint32_t*>(ptr) + 1); 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return c.d; 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#else 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return *reinterpret_cast<double*>(ptr); 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetFrameSlot(unsigned offset, intptr_t value) { 395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *GetFrameSlotPointer(offset) = value; 396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetRegister(unsigned n) const { 399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(n < ARRAY_SIZE(registers_)); 400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return registers_[n]; 401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double GetDoubleRegister(unsigned n) const { 404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(n < ARRAY_SIZE(double_registers_)); 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return double_registers_[n]; 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetRegister(unsigned n, intptr_t value) { 409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(n < ARRAY_SIZE(registers_)); 410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch registers_[n] = value; 411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetDoubleRegister(unsigned n, double value) { 414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(n < ARRAY_SIZE(double_registers_)); 415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double_registers_[n] = value; 416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetTop() const { return top_; } 419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetTop(intptr_t top) { top_ = top; } 420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetPc() const { return pc_; } 422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetPc(intptr_t pc) { pc_ = pc; } 423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetFp() const { return fp_; } 425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetFp(intptr_t fp) { fp_ = fp; } 426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t GetContext() const { return context_; } 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetContext(intptr_t context) { context_ = context; } 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Smi* GetState() const { return state_; } 431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetState(Smi* state) { state_ = state; } 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetContinuation(intptr_t pc) { continuation_ = pc; } 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StackFrame::Type GetFrameType() const { return type_; } 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetFrameType(StackFrame::Type type) { type_ = type; } 4373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the incoming arguments count. 4393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int ComputeParametersCount(); 4403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get a parameter value for an unoptimized frame. 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* GetParameter(int index); 4433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the expression stack height for a unoptimized frame. 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned GetExpressionCount(); 4463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the expression stack value for an unoptimized frame. 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* GetExpression(int index); 4493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int registers_offset() { 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, registers_); 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int double_registers_offset() { 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, double_registers_); 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int frame_size_offset() { 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, frame_size_); 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int pc_offset() { 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, pc_); 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int state_offset() { 467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, state_); 468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int continuation_offset() { 471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, continuation_); 472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int frame_content_offset() { 47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return OFFSET_OF(FrameDescription, frame_content_); 476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const uint32_t kZapUint32 = 0xbeeddead; 480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to 4823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // keep the variable-size array frame_content_ of type intptr_t at 4833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // the end of the structure aligned. 484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uintptr_t frame_size_; // Number of bytes. 485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function_; 486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t registers_[Register::kNumRegisters]; 487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double double_registers_[DoubleRegister::kNumAllocatableRegisters]; 488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t top_; 489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t pc_; 490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t fp_; 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t context_; 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StackFrame::Type type_; 493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Smi* state_; 4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef DEBUG 4953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code::Kind kind_; 4963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Continuation is the PC where the execution continues after 499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // deoptimizing. 500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t continuation_; 501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 50244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // This must be at the end of the object as the object is allocated larger 50344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // than it's definition indicate to extend this array. 50444f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t frame_content_[1]; 50544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t* GetFrameSlotPointer(unsigned offset) { 507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(offset < frame_size_); 508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return reinterpret_cast<intptr_t*>( 509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<Address>(this) + frame_content_offset() + offset); 510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int ComputeFixedSize(); 513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TranslationBuffer BASE_EMBEDDED { 517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationBuffer() : contents_(256) { } 519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int CurrentIndex() const { return contents_.length(); } 521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Add(int32_t value); 522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<ByteArray> CreateByteArray(); 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<uint8_t> contents_; 527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TranslationIterator BASE_EMBEDDED { 531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationIterator(ByteArray* buffer, int index) 533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : buffer_(buffer), index_(index) { 534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(index >= 0 && index < buffer->length()); 535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int32_t Next(); 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 53969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool HasNext() const { return index_ < buffer_->length(); } 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Skip(int n) { 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < n; i++) Next(); 543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ByteArray* buffer_; 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int index_; 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass Translation BASE_EMBEDDED { 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum Opcode { 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BEGIN, 5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JS_FRAME, 5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CONSTRUCT_STUB_FRAME, 5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ARGUMENTS_ADAPTOR_FRAME, 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch REGISTER, 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch INT32_REGISTER, 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DOUBLE_REGISTER, 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch STACK_SLOT, 562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch INT32_STACK_SLOT, 563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DOUBLE_STACK_SLOT, 564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LITERAL, 565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ARGUMENTS_OBJECT, 566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // A prefix indicating that the next command is a duplicate of the one 568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // that follows it. 569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DUPLICATE 570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count) 573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : buffer_(buffer), 574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch index_(buffer->CurrentIndex()) { 575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(BEGIN); 576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(frame_count); 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer_->Add(jsframe_count); 578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int index() const { return index_; } 581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Commands. 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void BeginJSFrame(int node_id, int literal_id, unsigned height); 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void BeginArgumentsAdaptorFrame(int literal_id, unsigned height); 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void BeginConstructStubFrame(int literal_id, unsigned height); 586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreRegister(Register reg); 587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreInt32Register(Register reg); 588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreDoubleRegister(DoubleRegister reg); 589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreStackSlot(int index); 590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreInt32StackSlot(int index); 591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreDoubleStackSlot(int index); 592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreLiteral(int literal_id); 593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreArgumentsObject(); 594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void MarkDuplicate(); 595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int NumberOfOperandsFor(Opcode opcode); 597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) 599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const char* StringFor(Opcode opcode); 600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationBuffer* buffer_; 604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int index_; 605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Linked list holding deoptimizing code objects. The deoptimizing code objects 609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// are kept as weak handles until they are no longer activated on the stack. 610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass DeoptimizingCodeListNode : public Malloced { 611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit DeoptimizingCodeListNode(Code* code); 613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ~DeoptimizingCodeListNode(); 614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizingCodeListNode* next() const { return next_; } 616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void set_next(DeoptimizingCodeListNode* next) { next_ = next; } 617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code() const { return code_; } 618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Global (weak) handle to the deoptimizing code object. 621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code_; 622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Next pointer for linked list. 624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizingCodeListNode* next_; 625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochclass SlotRef BASE_EMBEDDED { 6298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch public: 6308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch enum SlotRepresentation { 6318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch UNKNOWN, 6328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch TAGGED, 6338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch INT32, 6348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch DOUBLE, 6358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch LITERAL 6368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch }; 6378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SlotRef() 6398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : addr_(NULL), representation_(UNKNOWN) { } 6408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SlotRef(Address addr, SlotRepresentation representation) 6428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : addr_(addr), representation_(representation) { } 6438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit SlotRef(Object* literal) 6458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : literal_(literal), representation_(LITERAL) { } 6468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<Object> GetValue() { 6488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch switch (representation_) { 6498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case TAGGED: 6508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Handle<Object>(Memory::Object_at(addr_)); 6518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case INT32: { 6538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int value = Memory::int32_at(addr_); 6548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (Smi::IsValid(value)) { 6558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Handle<Object>(Smi::FromInt(value)); 6568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else { 6578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Isolate::Current()->factory()->NewNumberFromInt(value); 6588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case DOUBLE: { 6628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double value = Memory::double_at(addr_); 6638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Isolate::Current()->factory()->NewNumber(value); 6648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case LITERAL: 6678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return literal_; 6688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch default: 6708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch UNREACHABLE(); 6718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Handle<Object>::null(); 6728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static Vector<SlotRef> ComputeSlotMappingForArguments( 6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JavaScriptFrame* frame, 6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int inlined_frame_index, 6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int formal_parameter_count); 6798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private: 6818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address addr_; 6828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<Object> literal_; 6838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SlotRepresentation representation_; 6848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static Address SlotAddress(JavaScriptFrame* frame, int slot_index) { 6868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (slot_index >= 0) { 6878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch const int offset = JavaScriptFrameConstants::kLocal0Offset; 6888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return frame->fp() + offset - (slot_index * kPointerSize); 6898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else { 6908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch const int offset = JavaScriptFrameConstants::kLastParameterOffset; 6918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return frame->fp() + offset - ((slot_index + 1) * kPointerSize); 6928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator, 6968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch DeoptimizationInputData* data, 6978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch JavaScriptFrame* frame); 6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void ComputeSlotsForArguments( 7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Vector<SlotRef>* args_slots, 7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranslationIterator* iterator, 7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizationInputData* data, 7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JavaScriptFrame* frame); 7048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}; 7058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 7083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Class used to represent an unoptimized frame when the debugger 7093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// needs to inspect a frame that is part of an optimized frame. The 7103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// internally used FrameDescription objects are not GC safe so for use 7113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// by the debugger frame information is copied to an object of this type. 7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Represents parameters in unadapted form so their number might mismatch 7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// formal parameter count. 7143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass DeoptimizedFrameInfo : public Malloced { 7153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizedFrameInfo(Deoptimizer* deoptimizer, 7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int frame_index, 7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_arguments_adaptor, 7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_construct_stub); 7203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual ~DeoptimizedFrameInfo(); 7213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // GC support. 7233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void Iterate(ObjectVisitor* v); 7243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Return the number of incoming arguments. 7263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int parameters_count() { return parameters_count_; } 7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Return the height of the expression stack. 7293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int expression_count() { return expression_count_; } 7303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the frame function. 7323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JSFunction* GetFunction() { 7333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return function_; 7343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check if this frame is preceded by construct stub frame. The bottom-most 7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // inlined frame might still be called by an uninlined construct stub. 7383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool HasConstructStub() { 7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return has_construct_stub_; 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get an incoming argument. 7433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* GetParameter(int index) { 7443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(0 <= index && index < parameters_count()); 7453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return parameters_[index]; 7463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get an expression from the expression stack. 7493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* GetExpression(int index) { 7503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(0 <= index && index < expression_count()); 7513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return expression_stack_[index]; 7523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int GetSourcePosition() { 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return source_position_; 7563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 7593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Set an incoming argument. 7603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void SetParameter(int index, Object* obj) { 7613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(0 <= index && index < parameters_count()); 7623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch parameters_[index] = obj; 7633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Set an expression on the expression stack. 7663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void SetExpression(int index, Object* obj) { 7673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(0 <= index && index < expression_count()); 7683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch expression_stack_[index] = obj; 7693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JSFunction* function_; 7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_construct_stub_; 7733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int parameters_count_; 7743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int expression_count_; 7753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object** parameters_; 7763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object** expression_stack_; 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int source_position_; 7783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch friend class Deoptimizer; 7803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 7813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 7823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} } // namespace v8::internal 784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif // V8_DEOPTIMIZER_H_ 786