macro-assembler-ia32.h revision 6ded16be15dd865a9b21ea304d5273c8be299c87
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2009 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_IA32_MACRO_ASSEMBLER_IA32_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "assembler.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Convenience for platform-independent signatures. We do not normally 37e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// distinguish memory operands from other operands on ia32. 38e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketypedef Operand MemOperand; 39e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declaration. 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JumpTarget; 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// MacroAssembler implements a collection of frequently used macros. 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MacroAssembler: public Assembler { 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MacroAssembler(void* buffer, int size); 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GC Support 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Set the remebered set bit for an address which points into an 526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // object. RecordWriteHelper only works if the object is not in new 536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // space. 546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void RecordWriteHelper(Register object, 556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register addr, 566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register scratch); 576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check if object is in new space. 596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // scratch can be object itself, but it will be clobbered. 606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void InNewSpace(Register object, 616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register scratch, 626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Condition cc, // equal for new space, not_equal otherwise. 636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Label* branch); 646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the remembered set bit for [object+offset]. 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object is the object being stored into, value is the object being stored. 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If offset is zero, then the scratch register contains the array index into 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the elements array represented as a Smi. 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All registers are clobbered by the operation. 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void RecordWrite(Register object, 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offset, 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register value, 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch); 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugger Support 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SaveRegistersToMemory(RegList regs); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void RestoreRegistersFromMemory(RegList regs); 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void PushRegistersFromMemory(RegList regs); 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void PopRegistersToMemory(RegList regs); 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CopyRegistersFromStackToMemory(Register base, 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegList regs); 86402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void DebugBreak(); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 90d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Stack limit support 91d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 92d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Do simple test for stack overflow. This doesn't handle an overflow. 93d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void StackLimitCheck(Label* on_stack_limit_hit); 94d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 95d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // --------------------------------------------------------------------------- 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Activation frames 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); } 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); } 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Enter specific kind of exit frame; either in normal or debug mode. 105d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Expects the number of arguments in register eax and 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sets up the number of arguments in register edi and the pointer 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to the first argument in register esi. 108d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void EnterExitFrame(ExitFrame::Mode mode); 109d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 110d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void EnterApiExitFrame(ExitFrame::Mode mode, int stack_space, int argc); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Leave the current exit frame. Expects the return value in 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register eax:edx (untouched) and the pointer to the first 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // argument in register esi. 115d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void LeaveExitFrame(ExitFrame::Mode mode); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 117d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Find the function context up the context chain. 118d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void LoadContext(Register dst, int context_chain_length); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // JavaScript invokes 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Invoke the JavaScript function code by either calling or jumping. 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void InvokeCode(const Operand& code, 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& expected, 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& actual, 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InvokeFlag flag); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void InvokeCode(Handle<Code> code, 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& expected, 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& actual, 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode, 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InvokeFlag flag); 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Invoke the JavaScript function in the given register. Changes the 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // current context to the context in the function before invoking. 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void InvokeFunction(Register function, 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& actual, 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InvokeFlag flag); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 141402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void InvokeFunction(JSFunction* function, 142402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu const ParameterCount& actual, 143402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu InvokeFlag flag); 144402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Invoke specified builtin JavaScript function. Adds an entry to 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the unresolved list if the name does not resolve. 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag); 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Store the code object for the given builtin in the target register. 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GetBuiltinEntry(Register target, Builtins::JavaScript id); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Expression support 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Set(Register dst, const Immediate& x); 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Set(const Operand& dst, const Immediate& x); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compare object type for heap object. 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Incoming register is heap_object and outgoing register is map. 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CmpObjectType(Register heap_object, InstanceType type, Register map); 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compare instance type for map. 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CmpInstanceType(Register map, InstanceType type); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Check if the map of an object is equal to a specified map and 1643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // branch to label if not. Skip the smi check if not required 1653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // (object is known to be a heap object) 1663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void CheckMap(Register obj, 1673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Map> map, 1683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Label* fail, 1693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bool is_heap_object); 1703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 171e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Check if the object in register heap_object is a string. Afterwards the 172e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // register map contains the object map and the register instance_type 173e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // contains the instance_type. The registers map and instance_type can be the 174e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // same in which case it contains the instance type afterwards. Either of the 175e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // registers map and instance_type can be the same as heap_object. 176e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Condition IsObjectStringType(Register heap_object, 177e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register map, 178e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register instance_type); 179e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // FCmp is similar to integer cmp, but requires unsigned 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // jcc instructions (je, ja, jae, jb, jbe, je, and jz). 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void FCmp(); 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Smi tagging support. 185e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void SmiTag(Register reg) { 186e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(kSmiTag == 0); 1876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(kSmiTagSize == 1); 1886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block add(reg, Operand(reg)); 189e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 190e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void SmiUntag(Register reg) { 191e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke sar(reg, kSmiTagSize); 192e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 193e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 194402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // Abort execution if argument is not a number. Used in debug code. 1956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void AbortIfNotNumber(Register object); 1966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Abort execution if argument is not a smi. Used in debug code. 1986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void AbortIfNotSmi(Register object); 199402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Exception handling 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Push a new try handler and link into try handler chain. The return 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // address must be pushed before calling this helper. 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void PushTryHandler(CodeLocation try_location, HandlerType type); 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Unlink the stack handler on top of the stack from the try handler chain. 208e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void PopTryHandler(); 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Inline caching support 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generates code that verifies that the maps of objects in the 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype chain of object hasn't changed since the code was 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // generated and branches to the miss label if any map has. If 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // necessary the function also generates code for security check 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in case of global object holders. The scratch and holder 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // registers are always clobbered, but the object register is only 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // clobbered if it the same as the holder register. The function 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // returns a register containing the holder - either object_reg or 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // holder_reg. 222402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // The function can optionally (when save_at_depth != 223402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // kInvalidProtoDepth) save the object at the given depth by moving 224402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // it to [esp + kPointerSize]. 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register CheckMaps(JSObject* object, Register object_reg, 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, Register holder_reg, 227402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Register scratch, 228402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu int save_at_depth, 229402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Label* miss); 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generate code for checking access rights - used for security checks 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // on access to global objects across environments. The holder register 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is left untouched, but the scratch register is clobbered. 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CheckAccessGlobalProxy(Register holder_reg, 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss); 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocation support 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate an object in new space. If the new space is exhausted control 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // continues at the gc_required label. The allocated object is returned in 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // result and end of the new object is returned in result_end. The register 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scratch can be passed as no_reg in which case an additional object 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // reference will be added to the reloc info. The returned pointers in result 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and result_end have not yet been tagged as heap objects. If 248d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // result_contains_top_on_entry is true the content of result is known to be 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the allocation top on entry (could be result_end from a previous call to 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // AllocateInNewSpace). If result_contains_top_on_entry is true scratch 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // should be no_reg as it is never used. 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AllocateInNewSpace(int object_size, 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result_end, 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* gc_required, 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags); 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AllocateInNewSpace(int header_size, 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor element_size, 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register element_count, 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result_end, 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* gc_required, 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags); 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AllocateInNewSpace(Register object_size, 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result_end, 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* gc_required, 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags); 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Undo allocation in new space. The object passed and objects allocated after 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // it will no longer be allocated. Make sure that no pointers are left to the 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object(s) no longer allocated as they would be invalid when allocation is 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // un-done. 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UndoAllocationInNewSpace(Register object); 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate a heap number in new space with undefined value. The 2823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // register scratch2 can be passed as no_reg; the others must be 2833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // valid registers. Returns tagged pointer in result register, or 2843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // jumps to gc_required if new space is full. 2853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void AllocateHeapNumber(Register result, 2863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register scratch1, 2873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register scratch2, 2883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label* gc_required); 2893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 290d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Allocate a sequential string. All the header fields of the string object 291d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // are initialized. 292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void AllocateTwoByteString(Register result, 293d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register length, 294d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch1, 295d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch2, 296d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch3, 297d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Label* gc_required); 298d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void AllocateAsciiString(Register result, 299d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register length, 300d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch1, 301d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch2, 302d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch3, 303d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Label* gc_required); 304d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Allocate a raw cons string object. Only the map field of the result is 306d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // initialized. 307d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void AllocateConsString(Register result, 308d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch1, 309d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch2, 310d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Label* gc_required); 311d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void AllocateAsciiConsString(Register result, 312d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch1, 313d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch2, 314d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Label* gc_required); 315d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Support functions. 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if result is zero and op is negative. 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void NegativeZeroTest(Register result, Register op, Label* then_label); 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if result is zero and op is negative in code using jump targets. 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void NegativeZeroTest(CodeGenerator* cgen, 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register op, 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JumpTarget* then_target); 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if result is zero and any of op1 and op2 are negative. 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register scratch is destroyed, and it must be different from op2. 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void NegativeZeroTest(Register result, Register op1, Register op2, 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, Label* then_label); 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Try to get function prototype of a function and puts the value in 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the result register. Checks that the function really is a 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function and jumps to the miss label if the fast checks fail. The 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function register will be untouched; the other registers may be 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // clobbered. 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void TryGetFunctionPrototype(Register function, 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss); 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generates code for reporting that an illegal operation has 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // occurred. 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IllegalOperation(int num_arguments); 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Runtime calls 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 350e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Call a code stub. Generate the code if necessary. 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CallStub(CodeStub* stub); 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 353e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Call a code stub and return the code object called. Try to generate 354e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // the code if necessary. Do not perform a GC but instead return a retry 355e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // after GC failure. 356e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* TryCallStub(CodeStub* stub); 357e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 358e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Tail call a code stub (jump). Generate the code if necessary. 359d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void TailCallStub(CodeStub* stub); 360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 361e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Tail call a code stub (jump) and return the code object called. Try to 362e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // generate the code if necessary. Do not perform a GC but instead return 363e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // a retry after GC failure. 364e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* TryTailCallStub(CodeStub* stub); 365e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return from a code stub after popping its arguments. 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void StubReturn(int argc); 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call a runtime routine. 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CallRuntime(Runtime::Function* f, int num_arguments); 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3724515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Call a runtime function, returning the CodeStub object called. 373e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Try to generate the stub code if necessary. Do not perform a GC 374e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // but instead return a retry after GC failure. 375e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* TryCallRuntime(Runtime::Function* f, int num_arguments); 376e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Convenience function: Same as above, but takes the fid instead. 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CallRuntime(Runtime::FunctionId id, int num_arguments); 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 380402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // Convenience function: call an external reference. 381402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void CallExternalReference(ExternalReference ref, int num_arguments); 382402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 383e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Convenience function: Same as above, but takes the fid instead. 384e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* TryCallRuntime(Runtime::FunctionId id, int num_arguments); 385e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tail call of a runtime routine (jump). 3876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Like JumpToExternalReference, but also takes care of passing the number 3886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // of parameters. 3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void TailCallExternalReference(const ExternalReference& ext, 3906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int num_arguments, 3916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int result_size); 3926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Convenience function: tail call a runtime routine (jump). 3946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void TailCallRuntime(Runtime::FunctionId fid, 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_arguments, 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int result_size); 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Before calling a C-function from generated code, align arguments on stack. 3996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // After aligning the frame, arguments must be stored in esp[0], esp[4], 4006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // etc., not pushed. The argument count assumes all arguments are word sized. 4016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Some compilers/platforms require the stack to be aligned when calling 4026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // C++ code. 4036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Needs a scratch register to do some arithmetic. This register will be 4046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // trashed. 4056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void PrepareCallCFunction(int num_arguments, Register scratch); 4066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Calls a C function and cleans up the space for arguments allocated 4086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // by PrepareCallCFunction. The called function is not allowed to trigger a 4096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // garbage collection, since that might move the code and invalidate the 4106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // return address (unless this is somehow accounted for by the called 4116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // function). 4126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void CallCFunction(ExternalReference function, int num_arguments); 4136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void CallCFunction(Register function, int num_arguments); 4146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 415d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void PushHandleScope(Register scratch); 416d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 417d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Pops a handle scope using the specified scratch register and 418d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // ensuring that saved register, it is not no_reg, is left unchanged. 419d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void PopHandleScope(Register saved, Register scratch); 420d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 421e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // As PopHandleScope, but does not perform a GC. Instead, returns a 422e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // retry after GC failure object if GC is necessary. 423e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* TryPopHandleScope(Register saved, Register scratch); 424e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jump to a runtime routine. 4266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void JumpToExternalReference(const ExternalReference& ext); 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Utilities 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Ret(); 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 434e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Emit code to discard a non-negative number of pointer-sized elements 435e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // from the stack, clobbering only the esp register. 436e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void Drop(int element_count); 437e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 438e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void Call(Label* target) { call(target); } 439e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 440e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void Move(Register target, Handle<Object> value); 441e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> CodeObject() { return code_object_; } 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // StatsCounter support 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetCounter(StatsCounter* counter, int value); 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IncrementCounter(StatsCounter* counter, int value); 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void DecrementCounter(StatsCounter* counter, int value); 451d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void IncrementCounter(Condition cc, StatsCounter* counter, int value); 452d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void DecrementCounter(Condition cc, StatsCounter* counter, int value); 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugging 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calls Abort(msg) if the condition cc is not satisfied. 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use --debug_code to enable. 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Assert(Condition cc, const char* msg); 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Like Assert(), but always enabled. 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Check(Condition cc, const char* msg); 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print a message to stdout and abort execution. 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Abort(const char* msg); 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check that the stack is aligned. 4696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void CheckStackAlignment(); 4706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Verify restrictions about code generated in stubs. 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_generating_stub(bool value) { generating_stub_ = value; } 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool generating_stub() { return generating_stub_; } 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool allow_stub_calls() { return allow_stub_calls_; } 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 477d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // --------------------------------------------------------------------------- 478d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // String utilities. 479d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 480402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // Check whether the instance type represents a flat ascii string. Jump to the 481402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // label if not. If the instance type can be scratched specify same register 482402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // for both instance type and scratch. 483402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type, 484402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Register scratch, 4856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Label* on_not_flat_ascii_string); 486402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 487d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Checks if both objects are sequential ASCII strings, and jumps to label 488d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // if either is not. 489d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void JumpIfNotBothSequentialAsciiStrings(Register object1, 490d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register object2, 491d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register scratch1, 492d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register scratch2, 4936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Label* on_not_flat_ascii_strings); 494d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool generating_stub_; 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool allow_stub_calls_; 4983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // This handle will be patched with the code object on installation. 4993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Object> code_object_; 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Helper functions for generating invokes. 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void InvokePrologue(const ParameterCount& expected, 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& actual, 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code_constant, 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Operand& code_operand, 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* done, 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InvokeFlag flag); 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Activation support. 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void EnterFrame(StackFrame::Type type); 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void LeaveFrame(StackFrame::Type type); 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 513d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void EnterExitFramePrologue(ExitFrame::Mode mode); 514d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void EnterExitFrameEpilogue(ExitFrame::Mode mode, int argc); 515d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocation support helpers. 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void LoadAllocationTopHelper(Register result, 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result_end, 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags); 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateAllocationTopHelper(Register result_end, Register scratch); 522e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 523e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Helper for PopHandleScope. Allowed to perform a GC and returns 524e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and 525e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // possibly returns a failure object indicating an allocation failure. 526e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* PopHandleScopeHelper(Register saved, 527e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch, 528e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool gc_allowed); 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The code patcher is used to patch (typically) small parts of code e.g. for 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugging and other types of instrumentation. When using the code patcher 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the exact number of bytes specified must be emitted. Is not legal to emit 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// relocation information. If any of these constraints are violated it causes 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an assertion. 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CodePatcher { 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodePatcher(byte* address, int size); 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~CodePatcher(); 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Macro assembler to emit code. 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MacroAssembler* masm() { return &masm_; } 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* address_; // The address of the code being patched. 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int size_; // Number of bytes of the expected patch size. 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MacroAssembler masm_; // Macro assembler used to generate the code. 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Static helper functions. 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading a field from an object. 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline Operand FieldOperand(Register object, int offset) { 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Operand(object, offset - kHeapObjectTag); 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading an indexed field from an object. 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline Operand FieldOperand(Register object, 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register index, 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offset) { 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Operand(object, index, scale, offset - kHeapObjectTag); 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockextern void LogGeneratedCodeCoverage(const char* file_line); 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_STRINGIFY(x) #x 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) { \ 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* ia32_coverage_function = \ 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \ 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->pushfd(); \ 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->pushad(); \ 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \ 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->pop(eax); \ 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->popad(); \ 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->popfd(); \ 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } \ 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm-> 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) masm-> 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ 595