deoptimizer.h revision 3fb3ca8c7ca439d408449a395897395c0faae8d1
11e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Copyright 2011 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: 8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LargeObjectChunk* eager_deoptimization_entry_code_; 9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block LargeObjectChunk* 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 122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Deoptimizer* New(JSFunction* function, 123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType type, 124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned bailout_id, 125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address from, 12644f0eee88ff00398ff7f715fab053374d808c90dSteve Block int fp_to_sp_delta, 12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate); 12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block static Deoptimizer* Grab(Isolate* isolate); 12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 1313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The returned object with information on the optimized frame needs to be 1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // freed before another one can be generated. 1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame, 1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int frame_index, 1353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Isolate* isolate); 1363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info, 1373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Isolate* isolate); 1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 1393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Makes sure that there is enough room in the relocation 14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // information of a code object to perform lazy deoptimization 14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // patching. If there is not enough room a new relocation 14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // information object is allocated and comments are added until it 14444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // is big enough. 14544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code); 146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Deoptimize the function now. Its current optimized code will never be run 148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // again and any activations of the optimized code will get deoptimized when 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // execution returns. 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void DeoptimizeFunction(JSFunction* function); 151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Deoptimize all functions in the heap. 153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void DeoptimizeAll(); 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void DeoptimizeGlobalObject(JSObject* object); 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void VisitAllOptimizedFunctionsForContext( 158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Context* context, OptimizedFunctionVisitor* visitor); 159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void VisitAllOptimizedFunctionsForGlobalObject( 161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSObject* object, OptimizedFunctionVisitor* visitor); 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor* visitor); 164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The size in bytes of the code required at a lazy deopt patch site. 1661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static int patch_size(); 1671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Patch all stack guard checks in the unoptimized code to 1691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // unconditionally call replacement_code. 1701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void PatchStackCheckCode(Code* unoptimized_code, 1711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 1721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code); 1731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Patch stack guard check at instruction before pc_after in 1751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // the unoptimized code to unconditionally call replacement_code. 1761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void PatchStackCheckCodeAt(Address pc_after, 1771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 1781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code); 1791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Change all patched stack guard checks in the unoptimized code 1811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // back to a normal stack guard check. 1821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void RevertStackCheckCode(Code* unoptimized_code, 1831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 1841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code); 1851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Change all patched stack guard checks in the unoptimized code 1871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // back to a normal stack guard check. 1881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void RevertStackCheckCodeAt(Address pc_after, 1891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* check_code, 1901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code* replacement_code); 191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ~Deoptimizer(); 193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void MaterializeHeapNumbers(); 1953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 1963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void MaterializeHeapNumbersForDebuggerInspectableFrame( 1973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Address top, uint32_t size, DeoptimizedFrameInfo* info); 1983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static void ComputeOutputFrames(Deoptimizer* deoptimizer); 201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Address GetDeoptimizationEntry(int id, BailoutType type); 203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int GetDeoptimizationId(Address addr, BailoutType type); 2049fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block static int GetOutputInfo(DeoptimizationOutputData* data, 2059fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block unsigned node_id, 2069fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block SharedFunctionInfo* shared); 207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Code generation support. 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int input_offset() { return OFFSET_OF(Deoptimizer, input_); } 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int output_count_offset() { 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(Deoptimizer, output_count_); 212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int output_offset() { return OFFSET_OF(Deoptimizer, output_); } 214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static int GetDeoptimizedCodeCount(Isolate* isolate); 216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kNotDeoptimizationEntry = -1; 218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Generators for the deoptimization entry code. 220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch class EntryGenerator BASE_EMBEDDED { 221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EntryGenerator(MacroAssembler* masm, BailoutType type) 223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : masm_(masm), type_(type) { } 224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual ~EntryGenerator() { } 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Generate(); 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MacroAssembler* masm() const { return masm_; } 230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType type() const { return type_; } 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GeneratePrologue() { } 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MacroAssembler* masm_; 236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Deoptimizer::BailoutType type_; 237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch class TableEntryGenerator : public EntryGenerator { 240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TableEntryGenerator(MacroAssembler* masm, BailoutType type, int count) 242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : EntryGenerator(masm, type), count_(count) { } 243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GeneratePrologue(); 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int count() const { return count_; } 249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int count_; 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kNumberOfEntries = 4096; 255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 25644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Deoptimizer(Isolate* isolate, 25744f0eee88ff00398ff7f715fab053374d808c90dSteve Block JSFunction* function, 258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType type, 259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned bailout_id, 260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address from, 2613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int fp_to_sp_delta, 2623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code* optimized_code); 263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DeleteFrameDescriptions(); 264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoComputeOutputFrames(); 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoComputeOsrOutputFrame(); 267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoComputeFrame(TranslationIterator* iterator, int frame_index); 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoTranslateCommand(TranslationIterator* iterator, 269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int frame_index, 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned output_offset); 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Translate a command for OSR. Updates the input offset to be used for 272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the next command. Returns false if translation of the command failed 273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // (e.g., a number conversion failed) and may or may not have updated the 274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // input offset. 275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool DoOsrTranslateCommand(TranslationIterator* iterator, 276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int* input_offset); 277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned ComputeInputFrameSize() const; 279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned ComputeFixedSize(JSFunction* function) const; 280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned ComputeIncomingArgumentSize(JSFunction* function) const; 282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned ComputeOutgoingArgumentSize() const; 283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* ComputeLiteral(int index) const; 285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void AddDoubleValue(intptr_t slot_address, double value); 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static LargeObjectChunk* CreateCode(BailoutType type); 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void GenerateDeoptimizationEntries( 290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MacroAssembler* masm, int count, BailoutType type); 291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Weak handle callback for deoptimizing code objects. 293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void HandleWeakDeoptimizedCode( 294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Persistent<v8::Value> obj, void* data); 295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Code* FindDeoptimizingCodeFromAddress(Address addr); 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void RemoveDeoptimizingCode(Code* code); 297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Fill the input from from a JavaScript frame. This is used when 2993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // the debugger needs to inspect an optimized frame. For normal 3003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // deoptimizations the input frame is filled in generated code. 3013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void FillInputFrame(Address tos, JavaScriptFrame* frame); 3023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function_; 305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* optimized_code_; 306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned bailout_id_; 307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutType bailout_type_; 308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address from_; 309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int fp_to_sp_delta_; 310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Input frame description. 312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameDescription* input_; 313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Number of output frames. 314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int output_count_; 315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Array of output frame descriptions. 316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameDescription** output_; 317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_; 319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int table_entry_size_; 321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class FrameDescription; 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class DeoptimizingCodeListNode; 3243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch friend class DeoptimizedFrameInfo; 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass FrameDescription { 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameDescription(uint32_t frame_size, 331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function); 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void* operator new(size_t size, uint32_t frame_size) { 33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Subtracts kPointerSize, as the member frame_content_ already supplies 33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // the first element of the area to store the frame. 33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return malloc(size + frame_size - kPointerSize); 337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void operator delete(void* description) { 340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch free(description); 341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t GetFrameSize() const { 3443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_); 3453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return static_cast<uint32_t>(frame_size_); 3463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* GetFunction() const { return function_; } 349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned GetOffsetFromSlotIndex(Deoptimizer* deoptimizer, int slot_index); 351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetFrameSlot(unsigned offset) { 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return *GetFrameSlotPointer(offset); 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double GetDoubleFrameSlot(unsigned offset) { 357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return *reinterpret_cast<double*>(GetFrameSlotPointer(offset)); 358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetFrameSlot(unsigned offset, intptr_t value) { 361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *GetFrameSlotPointer(offset) = value; 362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetRegister(unsigned n) const { 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(n < ARRAY_SIZE(registers_)); 366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return registers_[n]; 367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double GetDoubleRegister(unsigned n) const { 370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(n < ARRAY_SIZE(double_registers_)); 371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return double_registers_[n]; 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetRegister(unsigned n, intptr_t value) { 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(n < ARRAY_SIZE(registers_)); 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch registers_[n] = value; 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetDoubleRegister(unsigned n, double value) { 380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(n < ARRAY_SIZE(double_registers_)); 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double_registers_[n] = value; 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetTop() const { return top_; } 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetTop(intptr_t top) { top_ = top; } 386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetPc() const { return pc_; } 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetPc(intptr_t pc) { pc_ = pc; } 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t GetFp() const { return fp_; } 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetFp(intptr_t fp) { fp_ = fp; } 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Smi* GetState() const { return state_; } 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetState(Smi* state) { state_ = state; } 395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SetContinuation(intptr_t pc) { continuation_ = pc; } 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef DEBUG 3993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code::Kind GetKind() const { return kind_; } 4003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void SetKind(Code::Kind kind) { kind_ = kind; } 4013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 4023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the incoming arguments count. 4043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int ComputeParametersCount(); 4053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get a parameter value for an unoptimized frame. 4073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* GetParameter(Deoptimizer* deoptimizer, int index); 4083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the expression stack height for a unoptimized frame. 4103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unsigned GetExpressionCount(Deoptimizer* deoptimizer); 4113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the expression stack value for an unoptimized frame. 4133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* GetExpression(Deoptimizer* deoptimizer, int index); 4143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int registers_offset() { 416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, registers_); 417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int double_registers_offset() { 420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, double_registers_); 421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int frame_size_offset() { 424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, frame_size_); 425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int pc_offset() { 428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, pc_); 429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int state_offset() { 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, state_); 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int continuation_offset() { 436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return OFFSET_OF(FrameDescription, continuation_); 437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int frame_content_offset() { 44044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return OFFSET_OF(FrameDescription, frame_content_); 441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const uint32_t kZapUint32 = 0xbeeddead; 445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to 4473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // keep the variable-size array frame_content_ of type intptr_t at 4483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // the end of the structure aligned. 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch uintptr_t frame_size_; // Number of bytes. 450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function_; 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t registers_[Register::kNumRegisters]; 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double double_registers_[DoubleRegister::kNumAllocatableRegisters]; 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t top_; 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t pc_; 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t fp_; 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Smi* state_; 4573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef DEBUG 4583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code::Kind kind_; 4593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Continuation is the PC where the execution continues after 462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // deoptimizing. 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t continuation_; 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 46544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // This must be at the end of the object as the object is allocated larger 46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // than it's definition indicate to extend this array. 46744f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t frame_content_[1]; 46844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch intptr_t* GetFrameSlotPointer(unsigned offset) { 470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(offset < frame_size_); 471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return reinterpret_cast<intptr_t*>( 472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<Address>(this) + frame_content_offset() + offset); 473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TranslationBuffer BASE_EMBEDDED { 478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationBuffer() : contents_(256) { } 480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int CurrentIndex() const { return contents_.length(); } 482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Add(int32_t value); 483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<ByteArray> CreateByteArray(); 485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<uint8_t> contents_; 488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TranslationIterator BASE_EMBEDDED { 492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationIterator(ByteArray* buffer, int index) 494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : buffer_(buffer), index_(index) { 495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(index >= 0 && index < buffer->length()); 496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int32_t Next(); 499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool HasNext() const { return index_ >= 0; } 501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Done() { index_ = -1; } 503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Skip(int n) { 505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < n; i++) Next(); 506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ByteArray* buffer_; 510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int index_; 511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass Translation BASE_EMBEDDED { 515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum Opcode { 517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BEGIN, 518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FRAME, 519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch REGISTER, 520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch INT32_REGISTER, 521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DOUBLE_REGISTER, 522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch STACK_SLOT, 523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch INT32_STACK_SLOT, 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DOUBLE_STACK_SLOT, 525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LITERAL, 526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ARGUMENTS_OBJECT, 527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // A prefix indicating that the next command is a duplicate of the one 529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // that follows it. 530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DUPLICATE 531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Translation(TranslationBuffer* buffer, int frame_count) 534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : buffer_(buffer), 535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch index_(buffer->CurrentIndex()) { 536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(BEGIN); 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch buffer_->Add(frame_count); 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int index() const { return index_; } 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Commands. 543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void BeginFrame(int node_id, int literal_id, unsigned height); 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreRegister(Register reg); 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreInt32Register(Register reg); 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreDoubleRegister(DoubleRegister reg); 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreStackSlot(int index); 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreInt32StackSlot(int index); 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreDoubleStackSlot(int index); 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreLiteral(int literal_id); 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void StoreArgumentsObject(); 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void MarkDuplicate(); 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int NumberOfOperandsFor(Opcode opcode); 555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const char* StringFor(Opcode opcode); 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationBuffer* buffer_; 562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int index_; 563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Linked list holding deoptimizing code objects. The deoptimizing code objects 567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// are kept as weak handles until they are no longer activated on the stack. 568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass DeoptimizingCodeListNode : public Malloced { 569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit DeoptimizingCodeListNode(Code* code); 571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ~DeoptimizingCodeListNode(); 572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizingCodeListNode* next() const { return next_; } 574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void set_next(DeoptimizingCodeListNode* next) { next_ = next; } 575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code() const { return code_; } 576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Global (weak) handle to the deoptimizing code object. 579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code_; 580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Next pointer for linked list. 582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizingCodeListNode* next_; 583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochclass SlotRef BASE_EMBEDDED { 5878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch public: 5888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch enum SlotRepresentation { 5898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch UNKNOWN, 5908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch TAGGED, 5918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch INT32, 5928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch DOUBLE, 5938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch LITERAL 5948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch }; 5958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 5968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SlotRef() 5978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : addr_(NULL), representation_(UNKNOWN) { } 5988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 5998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SlotRef(Address addr, SlotRepresentation representation) 6008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : addr_(addr), representation_(representation) { } 6018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit SlotRef(Object* literal) 6038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : literal_(literal), representation_(LITERAL) { } 6048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<Object> GetValue() { 6068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch switch (representation_) { 6078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case TAGGED: 6088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Handle<Object>(Memory::Object_at(addr_)); 6098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case INT32: { 6118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int value = Memory::int32_at(addr_); 6128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (Smi::IsValid(value)) { 6138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Handle<Object>(Smi::FromInt(value)); 6148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else { 6158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Isolate::Current()->factory()->NewNumberFromInt(value); 6168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case DOUBLE: { 6208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double value = Memory::double_at(addr_); 6218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Isolate::Current()->factory()->NewNumber(value); 6228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch case LITERAL: 6258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return literal_; 6268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch default: 6288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch UNREACHABLE(); 6298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Handle<Object>::null(); 6308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static void ComputeSlotMappingForArguments(JavaScriptFrame* frame, 6348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int inlined_frame_index, 6358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Vector<SlotRef>* args_slots); 6368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private: 6388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address addr_; 6398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<Object> literal_; 6408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SlotRepresentation representation_; 6418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static Address SlotAddress(JavaScriptFrame* frame, int slot_index) { 6438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (slot_index >= 0) { 6448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch const int offset = JavaScriptFrameConstants::kLocal0Offset; 6458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return frame->fp() + offset - (slot_index * kPointerSize); 6468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else { 6478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch const int offset = JavaScriptFrameConstants::kLastParameterOffset; 6488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return frame->fp() + offset - ((slot_index + 1) * kPointerSize); 6498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 6518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator, 6538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch DeoptimizationInputData* data, 6548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch JavaScriptFrame* frame); 6558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}; 6568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 6593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Class used to represent an unoptimized frame when the debugger 6603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// needs to inspect a frame that is part of an optimized frame. The 6613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// internally used FrameDescription objects are not GC safe so for use 6623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// by the debugger frame information is copied to an object of this type. 6633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass DeoptimizedFrameInfo : public Malloced { 6643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 6653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DeoptimizedFrameInfo(Deoptimizer* deoptimizer, int frame_index); 6663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual ~DeoptimizedFrameInfo(); 6673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // GC support. 6693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void Iterate(ObjectVisitor* v); 6703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Return the number of incoming arguments. 6723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int parameters_count() { return parameters_count_; } 6733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Return the height of the expression stack. 6753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int expression_count() { return expression_count_; } 6763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the frame function. 6783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JSFunction* GetFunction() { 6793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return function_; 6803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get an incoming argument. 6833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* GetParameter(int index) { 6843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(0 <= index && index < parameters_count()); 6853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return parameters_[index]; 6863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get an expression from the expression stack. 6893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* GetExpression(int index) { 6903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(0 <= index && index < expression_count()); 6913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return expression_stack_[index]; 6923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 6953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Set the frame function. 6963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void SetFunction(JSFunction* function) { 6973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch function_ = function; 6983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Set an incoming argument. 7013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void SetParameter(int index, Object* obj) { 7023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(0 <= index && index < parameters_count()); 7033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch parameters_[index] = obj; 7043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Set an expression on the expression stack. 7073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void SetExpression(int index, Object* obj) { 7083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(0 <= index && index < expression_count()); 7093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch expression_stack_[index] = obj; 7103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JSFunction* function_; 7133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int parameters_count_; 7143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int expression_count_; 7153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object** parameters_; 7163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object** expression_stack_; 7173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch friend class Deoptimizer; 7193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 7203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 7213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} } // namespace v8::internal 723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif // V8_DEOPTIMIZER_H_ 725