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. 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2009 the V8 project authors. All rights reserved. 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_ASSEMBLER_H_ 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_ASSEMBLER_H_ 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "runtime.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "top.h" 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "zone-inl.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "token.h" 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Labels represent pc locations; they are typically jump or call targets. 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// After declaration, a label can be freely used to denote known or (yet) 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// unknown pc location. Assembler::bind() is used to bind a label to the 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// current pc. A label can be bound only once. 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Label BASE_EMBEDDED { 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Label()) { Unuse(); } 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(~Label()) { ASSERT(!is_linked()); } 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(void Unuse()) { pos_ = 0; } 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(bool is_bound() const) { return pos_ < 0; } 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(bool is_unused() const) { return pos_ == 0; } 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(bool is_linked() const) { return pos_ > 0; } 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the position of bound or linked labels. Cannot be used 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for unused labels. 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos() const; 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pos_ encodes both the binding state (via its sign) 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and the binding position (via its value) of a label. 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pos_ < 0 bound label, pos() returns the jump target position 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pos_ == 0 unused label 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pos_ > 0 linked label, pos() returns the last reference position 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos_; 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind_to(int pos) { 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ = -pos - 1; 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_bound()); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void link_to(int pos) { 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ = pos + 1; 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_linked()); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class RegexpAssembler; 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Displacement; 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class ShadowTarget; 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class RegExpMacroAssemblerIrregexp; 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Relocation information 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Relocation information consists of the address (pc) of the datum 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to which the relocation information applies, the relocation mode 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (rmode), and an optional data field. The relocation mode may be 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "descriptive" and not indicate a need for relocation, but simply 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// describe a property of the datum. Such rmodes are useful for GC 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and nice disassembly output. 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RelocInfo BASE_EMBEDDED { 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The constant kNoPosition is used with the collecting of source positions 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in the relocation information. Two types of source positions are collected 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // "position" (RelocMode position) and "statement position" (RelocMode 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // statement_position). The "position" is collected at places in the source 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code which are of interest when making stack traces to pin-point the source 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // location of a stack frame as close as possible. The "statement position" is 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // collected at the beginning at each statement, and is used to indicate 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // possible break locations. kNoPosition is used to indicate an 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // invalid/uninitialized position value. 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kNoPosition = -1; 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Mode { 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Please note the order is important (see IsCodeTarget, IsGCRelocMode). 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CONSTRUCT_CALL, // code target that is a call to a JavaScript constructor. 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CODE_TARGET_CONTEXT, // code target used for contextual loads. 122402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu DEBUG_BREAK, 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CODE_TARGET, // code target which is not any of the above. 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMBEDDED_OBJECT, 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EMBEDDED_STRING, 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Everything after runtime_entry (inclusive) is not GC'ed. 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RUNTIME_ENTRY, 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JS_RETURN, // Marks start of the ExitJSFrame code. 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block COMMENT, 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block POSITION, // See comment for kNoPosition above. 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STATEMENT_POSITION, // See comment for kNoPosition above. 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EXTERNAL_REFERENCE, // The address of an external C++ function. 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INTERNAL_REFERENCE, // An address inside the same function. 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // add more as needed 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Pseudo-types 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NUMBER_OF_MODES, // must be no greater than 14 - see RelocInfoWriter 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NONE, // never recorded 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LAST_CODE_ENUM = CODE_TARGET, 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LAST_GCED_ENUM = EMBEDDED_STRING 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo() {} 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo(byte* pc, Mode rmode, intptr_t data) 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : pc_(pc), rmode_(rmode), data_(data) { 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsConstructCall(Mode mode) { 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == CONSTRUCT_CALL; 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsCodeTarget(Mode mode) { 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode <= LAST_CODE_ENUM; 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Is the relocation mode affected by GC? 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsGCRelocMode(Mode mode) { 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode <= LAST_GCED_ENUM; 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsJSReturn(Mode mode) { 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == JS_RETURN; 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsComment(Mode mode) { 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == COMMENT; 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsPosition(Mode mode) { 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == POSITION || mode == STATEMENT_POSITION; 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsStatementPosition(Mode mode) { 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == STATEMENT_POSITION; 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsExternalReference(Mode mode) { 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == EXTERNAL_REFERENCE; 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsInternalReference(Mode mode) { 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return mode == INTERNAL_REFERENCE; 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline int ModeMask(Mode mode) { return 1 << mode; } 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pc() const { return pc_; } 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_pc(byte* pc) { pc_ = pc; } 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Mode rmode() const { return rmode_; } 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block intptr_t data() const { return data_; } 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Apply a relocation by delta bytes 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(void apply(intptr_t delta)); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read/modify the code target in the branch/call instruction 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // this relocation applies to; 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // can only be called if IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Address target_address()); 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(void set_target_address(Address target)); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Object* target_object()); 1953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block INLINE(Handle<Object> target_object_handle(Assembler* origin)); 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Object** target_object_address()); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(void set_target_object(Object* target)); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read the address of the word containing the target_address. Can only 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // be called if IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY. 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Address target_address_address()); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read/modify the reference in the instruction this relocation 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // applies to; can only be called if rmode_ is external_reference 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Address* target_reference_address()); 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read/modify the address of a call instruction. This is used to relocate 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the break points where straight-line code is patched with a call 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // instruction. 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Address call_address()); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(void set_call_address(Address target)); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Object* call_object()); 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(Object** call_object_address()); 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(void set_call_object(Object* target)); 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code with some other code. 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void PatchCode(byte* instructions, int instruction_count); 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code with a call. 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void PatchCodeWithCall(Address target, int guard_bytes); 2213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Check whether this return sequence has been patched 2233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // with a call to the debugger. 2243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block INLINE(bool IsPatchedReturnSequence()); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DISASSEMBLER 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const char* RelocModeName(Mode rmode); 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Print(); 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // ENABLE_DISASSEMBLER 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugging 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Verify(); 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1; 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kPositionMask = 1 << POSITION | 1 << STATEMENT_POSITION; 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kDebugMask = kPositionMask | 1 << COMMENT; 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kApplyMask; // Modes affected by apply. Depends on arch. 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // On ARM, note that pc_ is the address of the constant pool entry 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to be relocated and not the address of the instruction 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // referencing the constant pool entry (except when rmode_ == 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // comment). 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pc_; 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Mode rmode_; 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block intptr_t data_; 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class RelocIterator; 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// RelocInfoWriter serializes a stream of relocation info. It writes towards 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// lower addresses. 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RelocInfoWriter BASE_EMBEDDED { 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfoWriter() : pos_(NULL), last_pc_(NULL), last_data_(0) {} 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfoWriter(byte* pos, byte* pc) : pos_(pos), last_pc_(pc), 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_data_(0) {} 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pos() const { return pos_; } 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* last_pc() const { return last_pc_; } 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Write(const RelocInfo* rinfo); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the state of the stream after reloc info buffer 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and/or code is moved while the stream is active. 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reposition(byte* pos, byte* pc) { 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ = pos; 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_pc_ = pc; 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Max size (bytes) of a written RelocInfo. Longest encoding is 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, ExtraTag, data_delta. 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // On ia32 and arm this is 1 + 4 + 1 + 1 + 1 + 4 = 12. 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // On x64 this is 1 + 4 + 1 + 1 + 1 + 8 == 16; 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Here we use the maximum of the two. 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMaxSize = 16; 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline uint32_t WriteVariableLengthPCJump(uint32_t pc_delta); 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteTaggedPC(uint32_t pc_delta, int tag); 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag); 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag); 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteTaggedData(intptr_t data_delta, int tag); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void WriteExtraTag(int extra_tag, int top_tag); 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pos_; 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* last_pc_; 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block intptr_t last_data_; 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter); 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A RelocIterator iterates over relocation information. 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Typical use: 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for (RelocIterator it(code); !it.done(); it.next()) { 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// // do something with it.rinfo() here 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// } 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A mask can be specified to skip unwanted modes. 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RelocIterator: public Malloced { 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a new iterator positioned at 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the beginning of the reloc info. 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Relocation information with mode k is included in the 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // iteration iff bit k of mode_mask is set. 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit RelocIterator(Code* code, int mode_mask = -1); 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit RelocIterator(const CodeDesc& desc, int mode_mask = -1); 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iteration 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return done_; } 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void next(); 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return pointer valid until next next(). 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo* rinfo() { 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return &rinfo_; 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Advance* moves the position before/after reading. 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // *Read* reads from current byte(s) into rinfo_. 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // *Get* just reads and returns info on current byte. 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(int bytes = 1) { pos_ -= bytes; } 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int AdvanceGetTag(); 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int GetExtraTag(); 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int GetTopTag(); 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ReadTaggedPC(); 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceReadPC(); 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceReadData(); 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceReadVariableLengthPCJump(); 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int GetPositionTypeTag(); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ReadTaggedData(); 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static RelocInfo::Mode DebugInfoModeFromTag(int tag); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the given mode is wanted, set it in rinfo_ and return true. 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Else return false. Used for efficiently skipping unwanted modes. 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool SetMode(RelocInfo::Mode mode) { 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (mode_mask_ & 1 << mode) ? (rinfo_.rmode_ = mode, true) : false; 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pos_; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* end_; 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo rinfo_; 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done_; 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int mode_mask_; 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(RelocIterator); 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//------------------------------------------------------------------------------ 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// External function 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//---------------------------------------------------------------------------- 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass IC_Utility; 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SCTableReference; 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Debug_Address; 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef void* ExternalReferenceRedirector(void* original, bool fp_return); 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An ExternalReference represents a C++ address used in the generated 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code. All references to C++ functions and variables must be encapsulated in 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an ExternalReference instance. This is done in order to track the origin of 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// all external references in the code so that they can be bound to the correct 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// addresses when deserializing a heap. 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExternalReference BASE_EMBEDDED { 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(Builtins::CFunctionId id); 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block explicit ExternalReference(ApiFunction* ptr); 378d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(Builtins::Name name); 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(Runtime::FunctionId id); 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(Runtime::Function* f); 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(const IC_Utility& ic_utility); 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(const Debug_Address& debug_address); 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(StatsCounter* counter); 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(Top::AddressId id); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(const SCTableReference& table_ref); 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One-of-a-kind references. These references are not part of a general 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pattern. This means that they have to be added to the 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ExternalReferenceTable in serialize.cc manually. 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference perform_gc_function(); 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference random_positive_smi_function(); 403402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static ExternalReference transcendental_cache_array_address(); 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 405e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Static data in the keyed lookup cache. 406e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static ExternalReference keyed_lookup_cache_keys(); 407e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static ExternalReference keyed_lookup_cache_field_offsets(); 408e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Static variable Factory::the_hole_value.location() 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference the_hole_value_location(); 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Static variable Heap::roots_address() 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference roots_address(); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Static variable StackGuard::address_of_jslimit() 416d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static ExternalReference address_of_stack_limit(); 417d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 418d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Static variable StackGuard::address_of_real_jslimit() 419d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static ExternalReference address_of_real_stack_limit(); 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Static variable RegExpStack::limit_address() 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference address_of_regexp_stack_limit(); 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 424e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Static variables for RegExp. 425e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static ExternalReference address_of_static_offsets_vector(); 426e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static ExternalReference address_of_regexp_stack_memory_address(); 427e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static ExternalReference address_of_regexp_stack_memory_size(); 428e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Static variable Heap::NewSpaceStart() 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference new_space_start(); 431402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static ExternalReference new_space_mask(); 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference heap_always_allocate_scope_depth(); 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used for fast allocation in generated code. 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference new_space_allocation_top_address(); 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference new_space_allocation_limit_address(); 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference double_fp_operation(Token::Value operation); 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference compare_doubles(); 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 441d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static ExternalReference handle_scope_extensions_address(); 442d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static ExternalReference handle_scope_next_address(); 443d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static ExternalReference handle_scope_limit_address(); 444d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 445d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static ExternalReference scheduled_exception_address(); 446d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address() const {return reinterpret_cast<Address>(address_);} 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function Debug::Break() 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference debug_break(); 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used to check if single stepping is enabled in generated code. 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference debug_step_in_fp_address(); 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef V8_NATIVE_REGEXP 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // C functions called from RegExp generated code. 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16() 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference re_case_insensitive_compare_uc16(); 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function RegExpMacroAssembler*::CheckStackGuardState() 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference re_check_stack_guard_state(); 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function NativeRegExpMacroAssembler::GrowStack() 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReference re_grow_stack(); 468e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 469e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // byte NativeRegExpMacroAssembler::word_character_bitmap 470e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static ExternalReference re_word_character_map(); 471e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This lets you register a function that rewrites all external references. 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used by the ARM simulator to catch calls to external references. 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void set_redirector(ExternalReferenceRedirector* redirector) { 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(redirector_ == NULL); // We can't stack them. 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block redirector_ = redirector; 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExternalReference(void* address) 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : address_(address) {} 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExternalReferenceRedirector* redirector_; 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void* Redirect(void* address, bool fp_return = false) { 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (redirector_ == NULL) return address; 489d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void* answer = (*redirector_)(address, fp_return); 490d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return answer; 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void* Redirect(Address address_arg, bool fp_return = false) { 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void* address = reinterpret_cast<void*>(address_arg); 495d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void* answer = (redirector_ == NULL) ? 496d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block address : 497d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block (*redirector_)(address, fp_return); 498d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return answer; 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void* address_; 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility functions 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_intn(int x, int n) { 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return -(1 << (n-1)) <= x && x < (1 << (n-1)); 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_int8(int x) { return is_intn(x, 8); } 5133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic inline bool is_int16(int x) { return is_intn(x, 16); } 5143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic inline bool is_int18(int x) { return is_intn(x, 18); } 5153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic inline bool is_int24(int x) { return is_intn(x, 24); } 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uintn(int x, int n) { 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (x & -(1 << n)) == 0; 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint2(int x) { return is_uintn(x, 2); } 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint3(int x) { return is_uintn(x, 3); } 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint4(int x) { return is_uintn(x, 4); } 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint5(int x) { return is_uintn(x, 5); } 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint6(int x) { return is_uintn(x, 6); } 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint8(int x) { return is_uintn(x, 8); } 5273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic inline bool is_uint10(int x) { return is_uintn(x, 10); } 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint12(int x) { return is_uintn(x, 12); } 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint16(int x) { return is_uintn(x, 16); } 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint24(int x) { return is_uintn(x, 24); } 5313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic inline bool is_uint26(int x) { return is_uintn(x, 26); } 5323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic inline bool is_uint28(int x) { return is_uintn(x, 28); } 5333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic inline int NumberOfBitsSet(uint32_t x) { 5353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu unsigned int num_bits_set; 5363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu for (num_bits_set = 0; x; x >>= 1) { 5373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu num_bits_set += x & 1; 5383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 5393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return num_bits_set; 5403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_ASSEMBLER_H_ 545