1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved. 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice, 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer. 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the distribution. 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission. 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modified significantly by Google Inc. 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_ASSEMBLER_H_ 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_ASSEMBLER_H_ 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "v8.h" 393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h" 413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "builtins.h" 42b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "gdb-jit.h" 433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "isolate.h" 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "runtime.h" 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "token.h" 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass ApiFunction; 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct StatsCounter; 54257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochconst unsigned kNoASTId = -1; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Platform independent assembler base class. 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass AssemblerBase: public Malloced { 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 60053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block explicit AssemblerBase(Isolate* isolate); 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate() const { return isolate_; } 63053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block int jit_cookie() { return jit_cookie_; } 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 65db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch // Overwrite a host NaN with a quiet target NaN. Used by mksnapshot for 66db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch // cross-snapshotting. 67db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch static void QuietNaN(HeapObject* nan) { } 68db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch 6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 71053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block int jit_cookie_; 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 74b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 75b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// ----------------------------------------------------------------------------- 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Labels represent pc locations; they are typically jump or call targets. 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// After declaration, a label can be freely used to denote known or (yet) 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// unknown pc location. Assembler::bind() is used to bind a label to the 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// current pc. A label can be bound only once. 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Label BASE_EMBEDDED { 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch enum Distance { 84257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kNear, kFar 85257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch }; 86257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 87257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch INLINE(Label()) { 88257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Unuse(); 89257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UnuseNear(); 90257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch INLINE(~Label()) { 933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(!is_linked()); 943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(!is_near_linked()); 953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch INLINE(void Unuse()) { pos_ = 0; } 983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch INLINE(void UnuseNear()) { near_link_pos_ = 0; } 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch INLINE(bool is_bound() const) { return pos_ < 0; } 1013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch INLINE(bool is_unused() const) { return pos_ == 0 && near_link_pos_ == 0; } 1023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch INLINE(bool is_linked() const) { return pos_ > 0; } 103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch INLINE(bool is_near_linked() const) { return near_link_pos_ > 0; } 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the position of bound or linked labels. Cannot be used 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for unused labels. 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos() const; 108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int near_link_pos() const { return near_link_pos_ - 1; } 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pos_ encodes both the binding state (via its sign) 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and the binding position (via its value) of a label. 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pos_ < 0 bound label, pos() returns the jump target position 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pos_ == 0 unused label 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pos_ > 0 linked label, pos() returns the last reference position 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos_; 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Behaves like |pos_| in the "> 0" case, but for near jumps to this label. 120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int near_link_pos_; 121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind_to(int pos) { 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ = -pos - 1; 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_bound()); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void link_to(int pos, Distance distance = kFar) { 127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (distance == kNear) { 128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch near_link_pos_ = pos + 1; 129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(is_near_linked()); 130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch pos_ = pos + 1; 132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(is_linked()); 133257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class RegexpAssembler; 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Displacement; 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class RegExpMacroAssemblerIrregexp; 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs }; 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Relocation information 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Relocation information consists of the address (pc) of the datum 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to which the relocation information applies, the relocation mode 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (rmode), and an optional data field. The relocation mode may be 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "descriptive" and not indicate a need for relocation, but simply 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// describe a property of the datum. Such rmodes are useful for GC 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and nice disassembly output. 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RelocInfo BASE_EMBEDDED { 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The constant kNoPosition is used with the collecting of source positions 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in the relocation information. Two types of source positions are collected 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // "position" (RelocMode position) and "statement position" (RelocMode 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // statement_position). The "position" is collected at places in the source 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code which are of interest when making stack traces to pin-point the source 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // location of a stack frame as close as possible. The "statement position" is 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // collected at the beginning at each statement, and is used to indicate 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // possible break locations. kNoPosition is used to indicate an 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // invalid/uninitialized position value. 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kNoPosition = -1; 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // This string is used to add padding comments to the reloc info in cases 171e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // where we are not sure to have enough space for patching in during 172e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // lazy deoptimization. This is the case if we have indirect calls for which 173e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // we do not normally record relocation info. 17469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static const char* const kFillerCommentString; 175e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 176e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The minimum size of a comment is equal to three bytes for the extra tagged 177e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // pc + the tag for the data, and kPointerSize for the actual pointer to the 178e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // comment. 179e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static const int kMinRelocCommentSize = 3 + kPointerSize; 180e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 181e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The maximum size for a call instruction including pc-jump. 182e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static const int kMaxCallSize = 6; 183e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 18444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // The maximum pc delta that will use the short encoding. 18544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const int kMaxSmallPCDelta; 18644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Mode { 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Please note the order is important (see IsCodeTarget, IsGCRelocMode). 189257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CODE_TARGET, // Code target which is not any of the above. 190257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CODE_TARGET_WITH_ID, 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CONSTRUCT_CALL, // code target that is a call to a JavaScript constructor. 1921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CODE_TARGET_CONTEXT, // Code target used for contextual loads and stores. 1937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DEBUG_BREAK, // Code target for the debugger statement. 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMBEDDED_OBJECT, 195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GLOBAL_PROPERTY_CELL, 196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Everything after runtime_entry (inclusive) is not GC'ed. 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RUNTIME_ENTRY, 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JS_RETURN, // Marks start of the ExitJSFrame code. 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block COMMENT, 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block POSITION, // See comment for kNoPosition above. 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STATEMENT_POSITION, // See comment for kNoPosition above. 2037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DEBUG_BREAK_SLOT, // Additional code inserted for debug break slot. 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EXTERNAL_REFERENCE, // The address of an external C++ function. 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INTERNAL_REFERENCE, // An address inside the same function. 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // add more as needed 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Pseudo-types 209257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NUMBER_OF_MODES, // There are at most 14 modes with noncompact encoding. 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NONE, // never recorded 211257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LAST_CODE_ENUM = DEBUG_BREAK, 212257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LAST_GCED_ENUM = GLOBAL_PROPERTY_CELL, 213257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Modes <= LAST_COMPACT_ENUM are guaranteed to have compact encoding. 214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo() {} 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo(byte* pc, Mode rmode, intptr_t data, Code* host) 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : pc_(pc), rmode_(rmode), data_(data), host_(host) { 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsConstructCall(Mode mode) { 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == CONSTRUCT_CALL; 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsCodeTarget(Mode mode) { 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode <= LAST_CODE_ENUM; 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline bool IsEmbeddedObject(Mode mode) { 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return mode == EMBEDDED_OBJECT; 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Is the relocation mode affected by GC? 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsGCRelocMode(Mode mode) { 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode <= LAST_GCED_ENUM; 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsJSReturn(Mode mode) { 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == JS_RETURN; 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsComment(Mode mode) { 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == COMMENT; 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsPosition(Mode mode) { 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == POSITION || mode == STATEMENT_POSITION; 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsStatementPosition(Mode mode) { 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == STATEMENT_POSITION; 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsExternalReference(Mode mode) { 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == EXTERNAL_REFERENCE; 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsInternalReference(Mode mode) { 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == INTERNAL_REFERENCE; 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static inline bool IsDebugBreakSlot(Mode mode) { 2567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return mode == DEBUG_BREAK_SLOT; 2577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline int ModeMask(Mode mode) { return 1 << mode; } 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors 2610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen byte* pc() const { return pc_; } 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_pc(byte* pc) { pc_ = pc; } 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Mode rmode() const { return rmode_; } 2640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen intptr_t data() const { return data_; } 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* host() const { return host_; } 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Apply a relocation by delta bytes 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(void apply(intptr_t delta)); 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 270f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Is the pointer this relocation info refers to coded like a plain pointer 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // or is it strange in some way (e.g. relative or patched into a series of 272f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // instructions). 273f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke bool IsCodedSpecially(); 274f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read/modify the code target in the branch/call instruction 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // this relocation applies to; 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // can only be called if IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Address target_address()); 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INLINE(void set_target_address(Address target, 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Object* target_object()); 2823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block INLINE(Handle<Object> target_object_handle(Assembler* origin)); 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Object** target_object_address()); 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INLINE(void set_target_object(Object* target, 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch INLINE(JSGlobalPropertyCell* target_cell()); 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch INLINE(Handle<JSGlobalPropertyCell> target_cell_handle()); 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INLINE(void set_target_cell(JSGlobalPropertyCell* cell, 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); 290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 292f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Read the address of the word containing the target_address in an 293f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // instruction stream. What this means exactly is architecture-independent. 294f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // The only architecture-independent user of this function is the serializer. 295f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // The serializer uses it to find out how many raw bytes of instruction to 296f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // output before the next target. Architecture-independent code shouldn't 297f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // dereference the pointer it gets back from this. 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Address target_address_address()); 299f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // This indicates how much space a target takes up when deserializing a code 300f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // stream. For most architectures this is just the size of a pointer. For 301f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // an instruction like movw/movt where the target bits are mixed into the 302f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // instruction bits the size of the target will be zero, indicating that the 303f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // serializer should not step forwards in memory after a target is resolved 304f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // and written. In this case the target_address_address function above 305f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // should return the end of the instructions to be patched, allowing the 306f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // deserializer to deserialize the instructions as raw bytes and put them in 307f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // place, ready to be patched with the target. 308f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke INLINE(int target_address_size()); 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read/modify the reference in the instruction this relocation 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // applies to; can only be called if rmode_ is external_reference 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Address* target_reference_address()); 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read/modify the address of a call instruction. This is used to relocate 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the break points where straight-line code is patched with a call 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // instruction. 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Address call_address()); 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(void set_call_address(Address target)); 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Object* call_object()); 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(void set_call_object(Object* target)); 321bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch INLINE(Object** call_object_address()); 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block template<typename StaticVisitor> inline void Visit(Heap* heap); 324f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke inline void Visit(ObjectVisitor* v); 325f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code with some other code. 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void PatchCode(byte* instructions, int instruction_count); 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code with a call. 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void PatchCodeWithCall(Address target, int guard_bytes); 3313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Check whether this return sequence has been patched 3333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // with a call to the debugger. 3343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block INLINE(bool IsPatchedReturnSequence()); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check whether this debug break slot has been patched with a call to the 3377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // debugger. 3387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch INLINE(bool IsPatchedDebugBreakSlotSequence()); 3397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DISASSEMBLER 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const char* RelocModeName(Mode rmode); 343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Print(FILE* out); 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // ENABLE_DISASSEMBLER 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugging 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Verify(); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1; 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kPositionMask = 1 << POSITION | 1 << STATEMENT_POSITION; 352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kDataMask = 353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch (1 << CODE_TARGET_WITH_ID) | kPositionMask | (1 << COMMENT); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kApplyMask; // Modes affected by apply. Depends on arch. 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // On ARM, note that pc_ is the address of the constant pool entry 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to be relocated and not the address of the instruction 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // referencing the constant pool entry (except when rmode_ == 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // comment). 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pc_; 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Mode rmode_; 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block intptr_t data_; 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* host_; 365257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef V8_TARGET_ARCH_MIPS 366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Code and Embedded Object pointers in mips are stored split 367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // across two consecutive 32-bit instructions. Heap management 368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // routines expect to access these pointers indirectly. The following 369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // location provides a place for these pointers to exist natually 370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // when accessed via the Iterator. 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* reconstructed_obj_ptr_; 372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // External-reference pointers are also split across instruction-pairs 373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // in mips, but are accessed via indirect pointers. This location 374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // provides a place for that pointer to exist naturally. Its address 375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // is returned by RelocInfo::target_reference_address(). 376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Address reconstructed_adr_ptr_; 377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif // V8_TARGET_ARCH_MIPS 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class RelocIterator; 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// RelocInfoWriter serializes a stream of relocation info. It writes towards 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// lower addresses. 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RelocInfoWriter BASE_EMBEDDED { 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfoWriter() : pos_(NULL), 387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch last_pc_(NULL), 388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch last_id_(0), 389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch last_position_(0) {} 390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfoWriter(byte* pos, byte* pc) : pos_(pos), 391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch last_pc_(pc), 392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch last_id_(0), 393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch last_position_(0) {} 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pos() const { return pos_; } 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* last_pc() const { return last_pc_; } 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Write(const RelocInfo* rinfo); 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the state of the stream after reloc info buffer 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and/or code is moved while the stream is active. 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reposition(byte* pos, byte* pc) { 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ = pos; 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc; 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Max size (bytes) of a written RelocInfo. Longest encoding is 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, ExtraTag, data_delta. 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // On ia32 and arm this is 1 + 4 + 1 + 1 + 1 + 4 = 12. 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // On x64 this is 1 + 4 + 1 + 1 + 1 + 8 == 16; 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Here we use the maximum of the two. 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMaxSize = 16; 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline uint32_t WriteVariableLengthPCJump(uint32_t pc_delta); 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteTaggedPC(uint32_t pc_delta, int tag); 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag); 418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch inline void WriteExtraTaggedIntData(int data_delta, int top_tag); 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag); 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteTaggedData(intptr_t data_delta, int tag); 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteExtraTag(int extra_tag, int top_tag); 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pos_; 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* last_pc_; 425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int last_id_; 426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int last_position_; 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A RelocIterator iterates over relocation information. 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Typical use: 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for (RelocIterator it(code); !it.done(); it.next()) { 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// // do something with it.rinfo() here 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// } 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A mask can be specified to skip unwanted modes. 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RelocIterator: public Malloced { 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a new iterator positioned at 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the beginning of the reloc info. 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Relocation information with mode k is included in the 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // iteration iff bit k of mode_mask is set. 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit RelocIterator(Code* code, int mode_mask = -1); 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit RelocIterator(const CodeDesc& desc, int mode_mask = -1); 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iteration 4490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool done() const { return done_; } 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void next(); 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return pointer valid until next next(). 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo* rinfo() { 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return &rinfo_; 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Advance* moves the position before/after reading. 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // *Read* reads from current byte(s) into rinfo_. 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // *Get* just reads and returns info on current byte. 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(int bytes = 1) { pos_ -= bytes; } 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int AdvanceGetTag(); 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int GetExtraTag(); 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int GetTopTag(); 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ReadTaggedPC(); 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceReadPC(); 468257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void AdvanceReadId(); 469257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void AdvanceReadPosition(); 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceReadData(); 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceReadVariableLengthPCJump(); 472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int GetLocatableTypeTag(); 473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void ReadTaggedId(); 474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void ReadTaggedPosition(); 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the given mode is wanted, set it in rinfo_ and return true. 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Else return false. Used for efficiently skipping unwanted modes. 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool SetMode(RelocInfo::Mode mode) { 479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return (mode_mask_ & (1 << mode)) ? (rinfo_.rmode_ = mode, true) : false; 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pos_; 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* end_; 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo rinfo_; 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done_; 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int mode_mask_; 487257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int last_id_; 488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int last_position_; 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(RelocIterator); 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//------------------------------------------------------------------------------ 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// External function 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//---------------------------------------------------------------------------- 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass IC_Utility; 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SCTableReference; 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Debug_Address; 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An ExternalReference represents a C++ address used in the generated 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code. All references to C++ functions and variables must be encapsulated in 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an ExternalReference instance. This is done in order to track the origin of 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// all external references in the code so that they can be bound to the correct 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// addresses when deserializing a heap. 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExternalReference BASE_EMBEDDED { 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 5111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Used in the simulator to support different native api calls. 5121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block enum Type { 513e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Builtin call. 514e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // MaybeObject* f(v8::internal::Arguments). 5151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block BUILTIN_CALL, // default 516e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Builtin that takes float arguments and returns an int. 518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // int f(double, double). 519257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BUILTIN_COMPARE_CALL, 520257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 521e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Builtin call that returns floating point. 522e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // double f(double, double). 523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BUILTIN_FP_FP_CALL, 524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 525257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Builtin call that returns floating point. 526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // double f(double). 527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BUILTIN_FP_CALL, 528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Builtin call that returns floating point. 530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // double f(double, int). 531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BUILTIN_FP_INT_CALL, 532e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 533e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Direct call to API function callback. 534e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Handle<Value> f(v8::Arguments&) 535e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DIRECT_API_CALL, 536e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 537e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Direct call to accessor getter callback. 538e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Handle<value> f(Local<String> property, AccessorInfo& info) 539e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DIRECT_GETTER_CALL 5401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 5411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block typedef void* ExternalReferenceRedirector(void* original, Type type); 5431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 54444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(Builtins::CFunctionId id, Isolate* isolate); 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 54644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(ApiFunction* ptr, Type type, Isolate* isolate); 547d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 54844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(Builtins::Name name, Isolate* isolate); 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(Runtime::FunctionId id, Isolate* isolate); 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(const Runtime::Function* f, Isolate* isolate); 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(const IC_Utility& ic_utility, Isolate* isolate); 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 55744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(const Debug_Address& debug_address, Isolate* isolate); 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(StatsCounter* counter); 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(Isolate::AddressId id, Isolate* isolate); 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(const SCTableReference& table_ref); 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Isolate::Current() as an external reference. 56744f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference isolate_address(); 56844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One-of-a-kind references. These references are not part of a general 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pattern. This means that they have to be added to the 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ExternalReferenceTable in serialize.cc manually. 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference incremental_marking_record_write_function( 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate* isolate); 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference incremental_evacuation_record_write_function( 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate* isolate); 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference store_buffer_overflow_function( 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate* isolate); 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference flush_icache_function(Isolate* isolate); 58044f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference perform_gc_function(Isolate* isolate); 58144f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference fill_heap_number_with_random_function( 58244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate); 58344f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference random_uint32_function(Isolate* isolate); 58444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference transcendental_cache_array_address(Isolate* isolate); 58544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference delete_handle_scope_extensions(Isolate* isolate); 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference get_date_field_function(Isolate* isolate); 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference date_cache_stamp(Isolate* isolate); 5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Deoptimization support. 59144f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference new_deoptimizer_function(Isolate* isolate); 59244f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference compute_output_frames_function(Isolate* isolate); 593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 594e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Static data in the keyed lookup cache. 59544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference keyed_lookup_cache_keys(Isolate* isolate); 59644f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference keyed_lookup_cache_field_offsets(Isolate* isolate); 597e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Static variable Heap::roots_array_start() 5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference roots_array_start(Isolate* isolate); 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Static variable StackGuard::address_of_jslimit() 60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference address_of_stack_limit(Isolate* isolate); 603d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 604d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Static variable StackGuard::address_of_real_jslimit() 60544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference address_of_real_stack_limit(Isolate* isolate); 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Static variable RegExpStack::limit_address() 60844f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference address_of_regexp_stack_limit(Isolate* isolate); 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 610e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Static variables for RegExp. 61144f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference address_of_static_offsets_vector(Isolate* isolate); 61244f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference address_of_regexp_stack_memory_address( 61344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate); 61444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference address_of_regexp_stack_memory_size( 61544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate); 616e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Static variable Heap::NewSpaceStart() 61844f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference new_space_start(Isolate* isolate); 61944f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference new_space_mask(Isolate* isolate); 62044f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference heap_always_allocate_scope_depth(Isolate* isolate); 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference new_space_mark_bits(Isolate* isolate); 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Write barrier. 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference store_buffer_top(Isolate* isolate); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used for fast allocation in generated code. 62744f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference new_space_allocation_top_address(Isolate* isolate); 62844f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference new_space_allocation_limit_address(Isolate* isolate); 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 63044f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference double_fp_operation(Token::Value operation, 63144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate); 63244f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference compare_doubles(Isolate* isolate); 63344f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference power_double_double_function(Isolate* isolate); 63444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference power_double_int_function(Isolate* isolate); 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 636d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static ExternalReference handle_scope_next_address(); 637d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static ExternalReference handle_scope_limit_address(); 6385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck static ExternalReference handle_scope_level_address(); 639d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 64044f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference scheduled_exception_address(Isolate* isolate); 641d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Static variables containing common double constants. 643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static ExternalReference address_of_min_int(); 644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static ExternalReference address_of_one_half(); 645b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch static ExternalReference address_of_minus_zero(); 646257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static ExternalReference address_of_zero(); 647257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static ExternalReference address_of_uint8_max_value(); 648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static ExternalReference address_of_negative_infinity(); 6493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static ExternalReference address_of_canonical_non_hole_nan(); 6503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static ExternalReference address_of_the_hole_nan(); 651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 65244f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference math_sin_double_function(Isolate* isolate); 65344f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference math_cos_double_function(Isolate* isolate); 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static ExternalReference math_tan_double_function(Isolate* isolate); 65544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference math_log_double_function(Isolate* isolate); 656e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address() const {return reinterpret_cast<Address>(address_);} 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function Debug::Break() 66144f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference debug_break(Isolate* isolate); 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used to check if single stepping is enabled in generated code. 66444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference debug_step_in_fp_address(Isolate* isolate); 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifndef V8_INTERPRETED_REGEXP 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // C functions called from RegExp generated code. 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16() 67144f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference re_case_insensitive_compare_uc16(Isolate* isolate); 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function RegExpMacroAssembler*::CheckStackGuardState() 67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference re_check_stack_guard_state(Isolate* isolate); 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function NativeRegExpMacroAssembler::GrowStack() 67744f0eee88ff00398ff7f715fab053374d808c90dSteve Block static ExternalReference re_grow_stack(Isolate* isolate); 678e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 679e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // byte NativeRegExpMacroAssembler::word_character_bitmap 680e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static ExternalReference re_word_character_map(); 681e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This lets you register a function that rewrites all external references. 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used by the ARM simulator to catch calls to external references. 686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void set_redirector(Isolate* isolate, 687257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ExternalReferenceRedirector* redirector) { 68844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // We can't stack them. 689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(isolate->external_reference_redirector() == NULL); 690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->set_external_reference_redirector( 69144f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<ExternalReferenceRedirectorPointer*>(redirector)); 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(void* address) 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : address_(address) {} 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69844f0eee88ff00398ff7f715fab053374d808c90dSteve Block static void* Redirect(Isolate* isolate, 69944f0eee88ff00398ff7f715fab053374d808c90dSteve Block void* address, 7001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Type type = ExternalReference::BUILTIN_CALL) { 70144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReferenceRedirector* redirector = 70244f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<ExternalReferenceRedirector*>( 70344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->external_reference_redirector()); 70444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (redirector == NULL) return address; 70544f0eee88ff00398ff7f715fab053374d808c90dSteve Block void* answer = (*redirector)(address, type); 706d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return answer; 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block static void* Redirect(Isolate* isolate, 71044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address address_arg, 7111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Type type = ExternalReference::BUILTIN_CALL) { 71244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReferenceRedirector* redirector = 71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<ExternalReferenceRedirector*>( 71444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->external_reference_redirector()); 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void* address = reinterpret_cast<void*>(address_arg); 71644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void* answer = (redirector == NULL) ? 717d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block address : 71844f0eee88ff00398ff7f715fab053374d808c90dSteve Block (*redirector)(address, type); 719d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return answer; 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void* address_; 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 7273e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu// Position recording support 7283e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 729b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstruct PositionState { 730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PositionState() : current_position(RelocInfo::kNoPosition), 731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch written_position(RelocInfo::kNoPosition), 732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current_statement_position(RelocInfo::kNoPosition), 733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch written_statement_position(RelocInfo::kNoPosition) {} 734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int current_position; 736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int written_position; 737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int current_statement_position; 739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int written_statement_position; 740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7423e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 7433e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhuclass PositionsRecorder BASE_EMBEDDED { 7443e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu public: 7453e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu explicit PositionsRecorder(Assembler* assembler) 746b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : assembler_(assembler) { 747b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 748b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch gdbjit_lineinfo_ = NULL; 749b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 750b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 751b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 752b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 753b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ~PositionsRecorder() { 754b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch delete gdbjit_lineinfo_; 755b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 756b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 757b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void StartGDBJITLineInfoRecording() { 758b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (FLAG_gdbjit) { 759b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch gdbjit_lineinfo_ = new GDBJITLineInfo(); 760b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 761b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 762b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 763b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJITLineInfo* DetachGDBJITLineInfo() { 764b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJITLineInfo* lineinfo = gdbjit_lineinfo_; 765b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch gdbjit_lineinfo_ = NULL; // To prevent deallocation in destructor. 766b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return lineinfo; 767b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 768b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Set current position to pos. 771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void RecordPosition(int pos); 7723e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 7733e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Set current statement position to pos. 7743e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu void RecordStatementPosition(int pos); 7753e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 7763e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Write recorded positions to relocation information. 7773e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu bool WriteRecordedPositions(); 7783e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int current_position() const { return state_.current_position; } 7803e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int current_statement_position() const { 782b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return state_.current_statement_position; 783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7843e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 7853e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu private: 7863e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Assembler* assembler_; 787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PositionState state_; 788b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 789b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJITLineInfo* gdbjit_lineinfo_; 790b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 7913e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class PreservePositionScope; 7933e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DISALLOW_COPY_AND_ASSIGN(PositionsRecorder); 7953e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}; 7963e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 7973e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 798b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass PreservePositionScope BASE_EMBEDDED { 7993e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu public: 800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit PreservePositionScope(PositionsRecorder* positions_recorder) 8013e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu : positions_recorder_(positions_recorder), 802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch saved_state_(positions_recorder->state_) {} 8033e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ~PreservePositionScope() { 805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch positions_recorder_->state_ = saved_state_; 8063e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } 8073e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 8083e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu private: 8093e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu PositionsRecorder* positions_recorder_; 810b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const PositionState saved_state_; 811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 812b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DISALLOW_COPY_AND_ASSIGN(PreservePositionScope); 8133e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}; 8143e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 8153e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 8163e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu// ----------------------------------------------------------------------------- 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility functions 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_intn(int x, int n) { 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return -(1 << (n-1)) <= x && x < (1 << (n-1)); 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_int8(int x) { return is_intn(x, 8); } 8243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_int16(int x) { return is_intn(x, 16); } 8253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_int18(int x) { return is_intn(x, 18); } 8263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_int24(int x) { return is_intn(x, 24); } 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uintn(int x, int n) { 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (x & -(1 << n)) == 0; 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint2(int x) { return is_uintn(x, 2); } 8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint3(int x) { return is_uintn(x, 3); } 8343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint4(int x) { return is_uintn(x, 4); } 8353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint5(int x) { return is_uintn(x, 5); } 8363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint6(int x) { return is_uintn(x, 6); } 8373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint8(int x) { return is_uintn(x, 8); } 8383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint10(int x) { return is_uintn(x, 10); } 8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint12(int x) { return is_uintn(x, 12); } 8403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint16(int x) { return is_uintn(x, 16); } 8413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint24(int x) { return is_uintn(x, 24); } 8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint26(int x) { return is_uintn(x, 26); } 8433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool is_uint28(int x) { return is_uintn(x, 28); } 8443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline int NumberOfBitsSet(uint32_t x) { 8463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu unsigned int num_bits_set; 8473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu for (num_bits_set = 0; x; x >>= 1) { 8483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu num_bits_set += x & 1; 8493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 8503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return num_bits_set; 8513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool EvalComparison(Token::Value op, double op1, double op2); 8543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 855b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Computes pow(x, y) with the special cases in the spec for Math.pow. 856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochdouble power_double_int(double x, int y); 857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochdouble power_double_double(double x, double y); 858b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 859257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Helper class for generating code or data associated with the code 860257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// right after a call instruction. As an example this can be used to 861257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// generate safepoint data after calls for crankshaft. 862257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass CallWrapper { 863257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 864257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CallWrapper() { } 865257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual ~CallWrapper() { } 866257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Called just before emitting a call. Argument is the size of the generated 867257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // call code. 868257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual void BeforeCall(int call_size) const = 0; 869257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Called just after emitting a call, i.e., at the return site for the call. 870257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual void AfterCall() const = 0; 871257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 872257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 873257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass NullCallWrapper : public CallWrapper { 874257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 875257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NullCallWrapper() { } 876257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual ~NullCallWrapper() { } 877257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual void BeforeCall(int call_size) const { } 878257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual void AfterCall() const { } 879257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 880257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_ASSEMBLER_H_ 884