macro-assembler-ia32.h revision b0fe1620dcb4135ac3ab2d66ff93072373911299
1b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Copyright 2010 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" 32756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#include "type-info.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// Flags used for the AllocateInNewSpace functions. 3825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenenum AllocationFlags { 3925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // No special flags. 4025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen NO_ALLOCATION_FLAGS = 0, 4125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // Return the pointer to the allocated already tagged as a heap object. 4225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen TAG_OBJECT = 1 << 0, 4325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // The content of the result register already contains the allocation top in 4425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // new space. 4525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen RESULT_CONTAINS_TOP = 1 << 1 4625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}; 4725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 48e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Convenience for platform-independent signatures. We do not normally 49e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// distinguish memory operands from other operands on ia32. 50e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketypedef Operand MemOperand; 51e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declaration. 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JumpTarget; 54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass PostCallGenerator; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// MacroAssembler implements a collection of frequently used macros. 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MacroAssembler: public Assembler { 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MacroAssembler(void* buffer, int size); 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GC Support 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // For page containing |object| mark region covering |addr| dirty. 657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // RecordWriteHelper only works if the object is not in new 666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // space. 676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void RecordWriteHelper(Register object, 686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register addr, 696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register scratch); 706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check if object is in new space. 726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // scratch can be object itself, but it will be clobbered. 73b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch template <typename LabelType> 746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void InNewSpace(Register object, 756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register scratch, 766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Condition cc, // equal for new space, not_equal otherwise. 77b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LabelType* branch); 786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 798defd9ff6930b4e24729971a61cf7469daf119beSteve Block // For page containing |object| mark region covering [object+offset] 808defd9ff6930b4e24729971a61cf7469daf119beSteve Block // dirty. |object| is the object being stored into, |value| is the 818defd9ff6930b4e24729971a61cf7469daf119beSteve Block // object being stored. If offset is zero, then the scratch register 828defd9ff6930b4e24729971a61cf7469daf119beSteve Block // contains the array index into the elements array represented as a 838defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Smi. All registers are clobbered by the operation. RecordWrite 848defd9ff6930b4e24729971a61cf7469daf119beSteve Block // filters out smis so it does not update the write barrier if the 858defd9ff6930b4e24729971a61cf7469daf119beSteve Block // value is a smi. 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void RecordWrite(Register object, 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offset, 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register value, 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch); 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 918defd9ff6930b4e24729971a61cf7469daf119beSteve Block // For page containing |object| mark region covering |address| 928defd9ff6930b4e24729971a61cf7469daf119beSteve Block // dirty. |object| is the object being stored into, |value| is the 938defd9ff6930b4e24729971a61cf7469daf119beSteve Block // object being stored. All registers are clobbered by the 948defd9ff6930b4e24729971a61cf7469daf119beSteve Block // operation. RecordWrite filters out smis so it does not update the 958defd9ff6930b4e24729971a61cf7469daf119beSteve Block // write barrier if the value is a smi. 968defd9ff6930b4e24729971a61cf7469daf119beSteve Block void RecordWrite(Register object, 978defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register address, 988defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register value); 998defd9ff6930b4e24729971a61cf7469daf119beSteve Block 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugger Support 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void DebugBreak(); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Activation frames 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); } 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); } 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Enter specific kind of exit frame. Expects the number of 117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // arguments in register eax and sets up the number of arguments in 118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // register edi and the pointer to the first argument in register 119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // esi. 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void EnterExitFrame(bool save_doubles); 121d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void EnterApiExitFrame(int argc); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Leave the current exit frame. Expects the return value in 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register eax:edx (untouched) and the pointer to the first 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // argument in register esi. 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void LeaveExitFrame(bool save_doubles); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Leave the current exit frame. Expects the return value in 1308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // register eax (untouched). 1318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void LeaveApiExitFrame(); 1328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 133d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Find the function context up the context chain. 134d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void LoadContext(Register dst, int context_chain_length); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Load the global function with the given index. 13780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void LoadGlobalFunction(int index, Register function); 13880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 13980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Load the initial map from the global function. The registers 14080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // function and map can be the same. 14180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void LoadGlobalFunctionInitialMap(Register function, Register map); 14280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Push and pop the registers that can hold pointers. 144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void PushSafepointRegisters() { pushad(); } 145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void PopSafepointRegisters() { popad(); } 146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int SafepointRegisterStackIndex(int reg_code); 147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // JavaScript invokes 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Invoke the JavaScript function code by either calling or jumping. 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void InvokeCode(const Operand& code, 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& expected, 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& actual, 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch InvokeFlag flag, 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PostCallGenerator* post_call_generator = NULL); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void InvokeCode(Handle<Code> code, 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& expected, 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& actual, 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode, 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch InvokeFlag flag, 163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PostCallGenerator* post_call_generator = NULL); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Invoke the JavaScript function in the given register. Changes the 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // current context to the context in the function before invoking. 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void InvokeFunction(Register function, 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& actual, 169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch InvokeFlag flag, 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PostCallGenerator* post_call_generator = NULL); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 172402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void InvokeFunction(JSFunction* function, 173402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu const ParameterCount& actual, 174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch InvokeFlag flag, 175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PostCallGenerator* post_call_generator = NULL); 176402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Invoke specified builtin JavaScript function. Adds an entry to 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the unresolved list if the name does not resolve. 179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void InvokeBuiltin(Builtins::JavaScript id, 180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch InvokeFlag flag, 181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PostCallGenerator* post_call_generator = NULL); 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 183791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block // Store the function for the given builtin in the target register. 184791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block void GetBuiltinFunction(Register target, Builtins::JavaScript id); 185791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Store the code object for the given builtin in the target register. 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GetBuiltinEntry(Register target, Builtins::JavaScript id); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Expression support 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Set(Register dst, const Immediate& x); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Set(const Operand& dst, const Immediate& x); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compare object type for heap object. 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Incoming register is heap_object and outgoing register is map. 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CmpObjectType(Register heap_object, InstanceType type, Register map); 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compare instance type for map. 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CmpInstanceType(Register map, InstanceType type); 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Check if the map of an object is equal to a specified map and 2013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // branch to label if not. Skip the smi check if not required 2023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // (object is known to be a heap object) 2033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void CheckMap(Register obj, 2043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Map> map, 2053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Label* fail, 2063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bool is_heap_object); 2073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 208e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Check if the object in register heap_object is a string. Afterwards the 209e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // register map contains the object map and the register instance_type 210e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // contains the instance_type. The registers map and instance_type can be the 211e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // same in which case it contains the instance type afterwards. Either of the 212e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // registers map and instance_type can be the same as heap_object. 213e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Condition IsObjectStringType(Register heap_object, 214e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register map, 215e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register instance_type); 216e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if a heap object's type is in the JSObject range, not including 2187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // JSFunction. The object's map will be loaded in the map register. 2197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Any or all of the three registers may be the same. 2207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The contents of the scratch register will always be overwritten. 2217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void IsObjectJSObjectType(Register heap_object, 2227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Register map, 2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Register scratch, 2247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Label* fail); 2257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The contents of the scratch register will be overwritten. 2277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void IsInstanceJSObjectType(Register map, Register scratch, Label* fail); 2287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // FCmp is similar to integer cmp, but requires unsigned 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // jcc instructions (je, ja, jae, jb, jbe, je, and jz). 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void FCmp(); 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 233e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Smi tagging support. 234e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void SmiTag(Register reg) { 235e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(kSmiTag == 0); 2366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(kSmiTagSize == 1); 2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block add(reg, Operand(reg)); 238e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 239e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void SmiUntag(Register reg) { 240e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke sar(reg, kSmiTagSize); 241e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 242e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 243756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Modifies the register even if it does not contain a Smi! 244756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void SmiUntag(Register reg, TypeInfo info, Label* non_smi) { 245756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ASSERT(kSmiTagSize == 1); 246756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick sar(reg, kSmiTagSize); 247756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (info.IsSmi()) { 248756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ASSERT(kSmiTag == 0); 249756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick j(carry, non_smi); 250756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 251756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 252756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 253756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Modifies the register even if it does not contain a Smi! 254756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void SmiUntag(Register reg, Label* is_smi) { 255756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ASSERT(kSmiTagSize == 1); 256756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick sar(reg, kSmiTagSize); 257756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ASSERT(kSmiTag == 0); 258756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick j(not_carry, is_smi); 259756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 260756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 261756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Assumes input is a heap object. 262756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void JumpIfNotNumber(Register reg, TypeInfo info, Label* on_not_number); 263756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 264756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Assumes input is a heap number. Jumps on things out of range. Also jumps 265756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // on the min negative int32. Ignores frational parts. 266756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void ConvertToInt32(Register dst, 267756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Register src, // Can be the same as dst. 268756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Register scratch, // Can be no_reg or dst, but not src. 269756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick TypeInfo info, 270756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Label* on_not_int32); 271756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void LoadPowerOf2(XMMRegister dst, Register scratch, int power); 2730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 274402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // Abort execution if argument is not a number. Used in debug code. 2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void AbortIfNotNumber(Register object); 2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Abort execution if argument is not a smi. Used in debug code. 2786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void AbortIfNotSmi(Register object); 279402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 280756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Abort execution if argument is a smi. Used in debug code. 281756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void AbortIfSmi(Register object); 282756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 28380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Abort execution if argument is a string. Used in debug code. 28480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void AbortIfNotString(Register object); 28580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Exception handling 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Push a new try handler and link into try handler chain. The return 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // address must be pushed before calling this helper. 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void PushTryHandler(CodeLocation try_location, HandlerType type); 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 293e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Unlink the stack handler on top of the stack from the try handler chain. 294e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void PopTryHandler(); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Inline caching support 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generate code for checking access rights - used for security checks 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // on access to global objects across environments. The holder register 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is left untouched, but the scratch register is clobbered. 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CheckAccessGlobalProxy(Register holder_reg, 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss); 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocation support 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate an object in new space. If the new space is exhausted control 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // continues at the gc_required label. The allocated object is returned in 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // result and end of the new object is returned in result_end. The register 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scratch can be passed as no_reg in which case an additional object 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // reference will be added to the reloc info. The returned pointers in result 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and result_end have not yet been tagged as heap objects. If 316d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // result_contains_top_on_entry is true the content of result is known to be 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the allocation top on entry (could be result_end from a previous call to 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // AllocateInNewSpace). If result_contains_top_on_entry is true scratch 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // should be no_reg as it is never used. 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AllocateInNewSpace(int object_size, 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result_end, 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* gc_required, 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags); 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AllocateInNewSpace(int header_size, 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor element_size, 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register element_count, 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result_end, 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* gc_required, 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AllocateInNewSpace(Register object_size, 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result_end, 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* gc_required, 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags); 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Undo allocation in new space. The object passed and objects allocated after 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // it will no longer be allocated. Make sure that no pointers are left to the 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object(s) no longer allocated as they would be invalid when allocation is 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // un-done. 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UndoAllocationInNewSpace(Register object); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate a heap number in new space with undefined value. The 3503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // register scratch2 can be passed as no_reg; the others must be 3513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // valid registers. Returns tagged pointer in result register, or 3523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // jumps to gc_required if new space is full. 3533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void AllocateHeapNumber(Register result, 3543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register scratch1, 3553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register scratch2, 3563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label* gc_required); 3573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 358d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Allocate a sequential string. All the header fields of the string object 359d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // are initialized. 360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void AllocateTwoByteString(Register result, 361d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register length, 362d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch1, 363d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch2, 364d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch3, 365d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Label* gc_required); 366d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void AllocateAsciiString(Register result, 367d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register length, 368d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch1, 369d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch2, 370d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch3, 371d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Label* gc_required); 3729ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick void AllocateAsciiString(Register result, 3739ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int length, 3749ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick Register scratch1, 3759ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick Register scratch2, 3769ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick Label* gc_required); 377d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 378d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Allocate a raw cons string object. Only the map field of the result is 379d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // initialized. 380d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void AllocateConsString(Register result, 381d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch1, 382d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch2, 383d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Label* gc_required); 384d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void AllocateAsciiConsString(Register result, 385d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch1, 386d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Register scratch2, 387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Label* gc_required); 388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // All registers must be distinct. Only current_string needs valid contents 3908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // on entry. All registers may be invalid on exit. result_operand is 3918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // unchanged, padding_chars is updated correctly. 3928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // The top of new space must contain a sequential ascii string with 3938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // padding_chars bytes free in its top word. The sequential ascii string 3948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // current_string is concatenated to it, allocating the necessary amount 3958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // of new memory. 3968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void AppendStringToTopOfNewSpace( 3978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Register current_string, // Tagged pointer to string to copy. 3988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Register current_string_length, 3998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Register result_pos, 4008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Register scratch, 4018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Register new_padding_chars, 4028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Operand operand_result, 4038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Operand operand_padding_chars, 4048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Label* bailout); 4058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Support functions. 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if result is zero and op is negative. 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void NegativeZeroTest(Register result, Register op, Label* then_label); 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if result is zero and op is negative in code using jump targets. 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void NegativeZeroTest(CodeGenerator* cgen, 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register op, 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JumpTarget* then_target); 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if result is zero and any of op1 and op2 are negative. 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register scratch is destroyed, and it must be different from op2. 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void NegativeZeroTest(Register result, Register op1, Register op2, 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, Label* then_label); 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Try to get function prototype of a function and puts the value in 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the result register. Checks that the function really is a 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function and jumps to the miss label if the fast checks fail. The 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function register will be untouched; the other registers may be 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // clobbered. 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void TryGetFunctionPrototype(Register function, 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register result, 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss); 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generates code for reporting that an illegal operation has 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // occurred. 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IllegalOperation(int num_arguments); 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Picks out an array index from the hash field. 43880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Register use: 43980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // hash - holds the index's hash. Clobbered. 44080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // index - holds the overwritten index on exit. 44180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void IndexFromHash(Register hash, Register index); 44280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Runtime calls 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 446e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Call a code stub. Generate the code if necessary. 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CallStub(CodeStub* stub); 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 449e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Call a code stub and return the code object called. Try to generate 450e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // the code if necessary. Do not perform a GC but instead return a retry 451e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // after GC failure. 4525913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* TryCallStub(CodeStub* stub); 453e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 454e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Tail call a code stub (jump). Generate the code if necessary. 455d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void TailCallStub(CodeStub* stub); 456d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 457e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Tail call a code stub (jump) and return the code object called. Try to 458e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // generate the code if necessary. Do not perform a GC but instead return 459e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // a retry after GC failure. 4605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub); 461e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return from a code stub after popping its arguments. 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void StubReturn(int argc); 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call a runtime routine. 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CallRuntime(Runtime::Function* f, int num_arguments); 467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void CallRuntimeSaveDoubles(Runtime::FunctionId id); 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Call a runtime function, returning the CodeStub object called. 470e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Try to generate the stub code if necessary. Do not perform a GC 471e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // but instead return a retry after GC failure. 4725913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::Function* f, 4735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck int num_arguments); 474e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Convenience function: Same as above, but takes the fid instead. 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void CallRuntime(Runtime::FunctionId id, int num_arguments); 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 478e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Convenience function: Same as above, but takes the fid instead. 4795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::FunctionId id, 4805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck int num_arguments); 481e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 482bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Convenience function: call an external reference. 483bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch void CallExternalReference(ExternalReference ref, int num_arguments); 484bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tail call of a runtime routine (jump). 4866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Like JumpToExternalReference, but also takes care of passing the number 4876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // of parameters. 4886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void TailCallExternalReference(const ExternalReference& ext, 4896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int num_arguments, 4906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int result_size); 4916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Tail call of a runtime routine (jump). Try to generate the code if 4938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // necessary. Do not perform a GC but instead return a retry after GC failure. 4948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang MUST_USE_RESULT MaybeObject* TryTailCallExternalReference( 4958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const ExternalReference& ext, int num_arguments, int result_size); 4968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Convenience function: tail call a runtime routine (jump). 4986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void TailCallRuntime(Runtime::FunctionId fid, 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_arguments, 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int result_size); 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Convenience function: tail call a runtime routine (jump). Try to generate 5038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // the code if necessary. Do not perform a GC but instead return a retry after 5048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // GC failure. 5058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang MUST_USE_RESULT MaybeObject* TryTailCallRuntime(Runtime::FunctionId fid, 5068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int num_arguments, 5078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int result_size); 5088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 5096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Before calling a C-function from generated code, align arguments on stack. 5106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // After aligning the frame, arguments must be stored in esp[0], esp[4], 5116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // etc., not pushed. The argument count assumes all arguments are word sized. 5126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Some compilers/platforms require the stack to be aligned when calling 5136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // C++ code. 5146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Needs a scratch register to do some arithmetic. This register will be 5156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // trashed. 5166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void PrepareCallCFunction(int num_arguments, Register scratch); 5176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 5186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Calls a C function and cleans up the space for arguments allocated 5196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // by PrepareCallCFunction. The called function is not allowed to trigger a 5206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // garbage collection, since that might move the code and invalidate the 5216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // return address (unless this is somehow accounted for by the called 5226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // function). 5236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void CallCFunction(ExternalReference function, int num_arguments); 5246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void CallCFunction(Register function, int num_arguments); 5256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 5265913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Prepares stack to put arguments (aligns and so on). Reserves 5275913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // space for return value if needed (assumes the return value is a handle). 5285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Uses callee-saved esi to restore stack state after call. Arguments must be 5298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // stored in ApiParameterOperand(0), ApiParameterOperand(1) etc. Saves 5308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // context (esi). 5318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void PrepareCallApiFunction(int argc, Register scratch); 532d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 53390bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner // Calls an API function. Allocates HandleScope, extracts 5345913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // returned value from handle and propagates exceptions. 5358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Clobbers ebx, edi and caller-save registers. Restores context. 5368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // On return removes stack_space * kPointerSize (GCed). 5378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang MaybeObject* TryCallApiFunctionAndReturn(ApiFunction* function, 5388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int stack_space); 539e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jump to a runtime routine. 5416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void JumpToExternalReference(const ExternalReference& ext); 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang MaybeObject* TryJumpToExternalReference(const ExternalReference& ext); 5448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Utilities 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Ret(); 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 551e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Emit code to discard a non-negative number of pointer-sized elements 552e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // from the stack, clobbering only the esp register. 553e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void Drop(int element_count); 554e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 555e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void Call(Label* target) { call(target); } 556e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Emit call to the code we are currently generating. 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void CallSelf() { 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch call(self, RelocInfo::CODE_TARGET); 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Move if the registers are not identical. 5640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void Move(Register target, Register source); 5650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 566e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void Move(Register target, Handle<Object> value); 567e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> CodeObject() { return code_object_; } 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // StatsCounter support 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetCounter(StatsCounter* counter, int value); 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IncrementCounter(StatsCounter* counter, int value); 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void DecrementCounter(StatsCounter* counter, int value); 577d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void IncrementCounter(Condition cc, StatsCounter* counter, int value); 578d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void DecrementCounter(Condition cc, StatsCounter* counter, int value); 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugging 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calls Abort(msg) if the condition cc is not satisfied. 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use --debug_code to enable. 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Assert(Condition cc, const char* msg); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 588756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void AssertFastElements(Register elements); 589756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Like Assert(), but always enabled. 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Check(Condition cc, const char* msg); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print a message to stdout and abort execution. 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Abort(const char* msg); 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check that the stack is aligned. 5976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void CheckStackAlignment(); 5986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Verify restrictions about code generated in stubs. 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_generating_stub(bool value) { generating_stub_ = value; } 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool generating_stub() { return generating_stub_; } 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool allow_stub_calls() { return allow_stub_calls_; } 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 605d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // --------------------------------------------------------------------------- 606d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // String utilities. 607d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 608402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // Check whether the instance type represents a flat ascii string. Jump to the 609402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // label if not. If the instance type can be scratched specify same register 610402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // for both instance type and scratch. 611402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type, 612402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Register scratch, 6136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Label* on_not_flat_ascii_string); 614402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 615d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Checks if both objects are sequential ASCII strings, and jumps to label 616d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // if either is not. 617d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void JumpIfNotBothSequentialAsciiStrings(Register object1, 618d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register object2, 619d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register scratch1, 620d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register scratch2, 6216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Label* on_not_flat_ascii_strings); 622d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool generating_stub_; 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool allow_stub_calls_; 6263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // This handle will be patched with the code object on installation. 6273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Object> code_object_; 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Helper functions for generating invokes. 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void InvokePrologue(const ParameterCount& expected, 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& actual, 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code_constant, 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Operand& code_operand, 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* done, 635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch InvokeFlag flag, 636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PostCallGenerator* post_call_generator = NULL); 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Activation support. 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void EnterFrame(StackFrame::Type type); 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void LeaveFrame(StackFrame::Type type); 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 64280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void EnterExitFramePrologue(); 643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void EnterExitFrameEpilogue(int argc, bool save_doubles); 644d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void LeaveExitFrameEpilogue(); 6468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocation support helpers. 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void LoadAllocationTopHelper(Register result, 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags); 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateAllocationTopHelper(Register result_end, Register scratch); 652e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 653e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Helper for PopHandleScope. Allowed to perform a GC and returns 654e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and 655e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // possibly returns a failure object indicating an allocation failure. 6565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved, 6575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Register scratch, 6585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck bool gc_allowed); 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochtemplate <typename LabelType> 663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid MacroAssembler::InNewSpace(Register object, 664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register scratch, 665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Condition cc, 666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LabelType* branch) { 667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(cc == equal || cc == not_equal); 668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (Serializer::enabled()) { 669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Can't do arithmetic on external references if it might get serialized. 670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch mov(scratch, Operand(object)); 671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The mask isn't really an address. We load it as an external reference in 672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // case the size of the new space is different between the snapshot maker 673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // and the running system. 674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch and_(Operand(scratch), Immediate(ExternalReference::new_space_mask())); 675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cmp(Operand(scratch), Immediate(ExternalReference::new_space_start())); 676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch j(cc, branch); 677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int32_t new_space_start = reinterpret_cast<int32_t>( 679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ExternalReference::new_space_start().address()); 680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch lea(scratch, Operand(object, -new_space_start)); 681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch and_(scratch, Heap::NewSpaceMask()); 682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch j(cc, branch); 683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The code patcher is used to patch (typically) small parts of code e.g. for 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugging and other types of instrumentation. When using the code patcher 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the exact number of bytes specified must be emitted. Is not legal to emit 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// relocation information. If any of these constraints are violated it causes 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an assertion. 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CodePatcher { 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodePatcher(byte* address, int size); 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~CodePatcher(); 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Macro assembler to emit code. 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MacroAssembler* masm() { return &masm_; } 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* address_; // The address of the code being patched. 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int size_; // Number of bytes of the expected patch size. 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MacroAssembler masm_; // Macro assembler used to generate the code. 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Helper class for generating code or data associated with the code 708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// right after a call instruction. As an example this can be used to 709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// generate safepoint data after calls for crankshaft. 710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass PostCallGenerator { 711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PostCallGenerator() { } 713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual ~PostCallGenerator() { } 714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Generate() = 0; 715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Static helper functions. 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading a field from an object. 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline Operand FieldOperand(Register object, int offset) { 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Operand(object, offset - kHeapObjectTag); 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading an indexed field from an object. 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline Operand FieldOperand(Register object, 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register index, 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offset) { 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Operand(object, index, scale, offset - kHeapObjectTag); 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 7368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangstatic inline Operand ContextOperand(Register context, int index) { 7378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return Operand(context, Context::SlotOffset(index)); 7388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 7398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 7408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 7418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangstatic inline Operand GlobalObjectOperand() { 7428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return ContextOperand(esi, Context::GLOBAL_INDEX); 7438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 7448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 7458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 7465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// Generates an Operand for saving parameters after PrepareCallApiFunction. 7475913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckOperand ApiParameterOperand(int index); 7485913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockextern void LogGeneratedCodeCoverage(const char* file_line); 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_STRINGIFY(x) #x 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) { \ 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* ia32_coverage_function = \ 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \ 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->pushfd(); \ 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->pushad(); \ 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \ 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->pop(eax); \ 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->popad(); \ 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm->popfd(); \ 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } \ 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm-> 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) masm-> 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ 775