1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file. 4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifndef V8_X87_MACRO_ASSEMBLER_X87_H_ 6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define V8_X87_MACRO_ASSEMBLER_X87_H_ 7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/assembler.h" 970f84b889d80940eb3f6deafd85f0934aaff7269weiliang.lin@intel.com#include "src/bailout-reason.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/frames.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/globals.h" 12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 13864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 { 14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal { 15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Convenience for platform-independent signatures. We do not normally 17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// distinguish memory operands from other operands on ia32. 18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgtypedef Operand MemOperand; 19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; 21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; 2238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgenum PointersToHereCheck { 2338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org kPointersToHereMaybeInteresting, 2438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org kPointersToHereAreAlwaysInteresting 2538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org}; 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum RegisterValueType { 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org REGISTER_VALUE_IS_SMI, 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org REGISTER_VALUE_IS_INT32 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 34d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org#ifdef DEBUG 35d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.orgbool AreAliased(Register reg1, 36d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Register reg2, 37d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Register reg3 = no_reg, 38d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Register reg4 = no_reg, 39d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Register reg5 = no_reg, 40d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Register reg6 = no_reg, 41d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Register reg7 = no_reg, 42d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Register reg8 = no_reg); 43d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org#endif 44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// MacroAssembler implements a collection of frequently used macros. 47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass MacroAssembler: public Assembler { 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The isolate parameter can be NULL if the macro assembler should 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // not use isolate-dependent functionality. In this case, it's the 51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // responsibility of the caller to never invoke such function on the 52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // macro assembler. 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MacroAssembler(Isolate* isolate, void* buffer, int size); 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Load(Register dst, const Operand& src, Representation r); 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Store(Register src, const Operand& dst, Representation r); 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Operations on roots in the root-array. 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadRoot(Register destination, Heap::RootListIndex index); 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void StoreRoot(Register source, Register scratch, Heap::RootListIndex index); 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CompareRoot(Register with, Register scratch, Heap::RootListIndex index); 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // These methods can only be used with constant roots (i.e. non-writable 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // and not in new space). 64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CompareRoot(Register with, Heap::RootListIndex index); 65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CompareRoot(const Operand& with, Heap::RootListIndex index); 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // GC Support 69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum RememberedSetFinalAction { 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kReturnAtEnd, 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kFallThroughAtEnd 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record in the remembered set the fact that we have a pointer to new space 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // at the address pointed to by the addr register. Only works if addr is not 76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // in new space. 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RememberedSetHelper(Register object, // Used for debug code. 7806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register addr, Register scratch, 7906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org SaveFPRegsMode save_fp, 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RememberedSetFinalAction and_then); 81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckPageFlag(Register object, 83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mask, 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition cc, 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* condition_met, 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance condition_met_distance = Label::kFar); 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckPageFlagForMap( 90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> map, 91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mask, 92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition cc, 93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* condition_met, 94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance condition_met_distance = Label::kFar); 95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckMapDeprecated(Handle<Map> map, 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_deprecated); 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if object is in new space. Jumps if the object is not in new space. 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The register scratch can be object itself, but scratch will be clobbered. 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void JumpIfNotInNewSpace(Register object, 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* branch, 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar) { 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InNewSpace(object, scratch, zero, branch, distance); 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if object is in new space. Jumps if the object is in new space. 110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The register scratch can be object itself, but it will be clobbered. 111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void JumpIfInNewSpace(Register object, 112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* branch, 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar) { 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InNewSpace(object, scratch, not_zero, branch, distance); 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if an object has a given incremental marking color. Also uses ecx! 119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void HasColor(Register object, 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch0, 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* has_color, 123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance has_color_distance, 124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int first_bit, 125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int second_bit); 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void JumpIfBlack(Register object, 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch0, 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* on_black, 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance on_black_distance = Label::kFar); 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Checks the color of an object. If the object is already grey or black 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // then we just fall through, since it is already live. If it is white and 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we can determine that it doesn't need to be scanned, then we just mark it 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // black and fall through. For the rest we jump to the label so the 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // incremental marker can fix its assumptions. 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EnsureNotWhite(Register object, 139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, 140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch2, 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* object_is_white_and_not_data, 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance); 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Notify the garbage collector that we wrote a pointer into an object. 145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // |object| is the object being stored into, |value| is the object being 146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // stored. value and scratch registers are clobbered by the operation. 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The offset is the offset from the start of the object, not the offset from 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the tagged HeapObject pointer. For use with FieldOperand(reg, off). 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordWriteField( 15006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register object, int offset, Register value, Register scratch, 15106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org SaveFPRegsMode save_fp, 152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 15338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org SmiCheck smi_check = INLINE_SMI_CHECK, 15438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value = 15538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org kPointersToHereMaybeInteresting); 156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // As above, but the offset has the tag presubtracted. For use with 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Operand(reg, off). 159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordWriteContextSlot( 16006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register context, int offset, Register value, Register scratch, 16106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org SaveFPRegsMode save_fp, 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 16338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org SmiCheck smi_check = INLINE_SMI_CHECK, 16438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value = 16538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org kPointersToHereMaybeInteresting) { 16606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org RecordWriteField(context, offset + kHeapObjectTag, value, scratch, save_fp, 16706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org remembered_set_action, smi_check, 16838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org pointers_to_here_check_for_value); 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Notify the garbage collector that we wrote a pointer into a fixed array. 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // |array| is the array being stored into, |value| is the 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object being stored. |index| is the array index represented as a 174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Smi. All registers are clobbered by the operation RecordWriteArray 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // filters out smis so it does not update the write barrier if the 176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // value is a smi. 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordWriteArray( 17806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register array, Register value, Register index, SaveFPRegsMode save_fp, 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 18038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org SmiCheck smi_check = INLINE_SMI_CHECK, 18138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value = 18238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org kPointersToHereMaybeInteresting); 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For page containing |object| mark region covering |address| 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // dirty. |object| is the object being stored into, |value| is the 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object being stored. The address and value registers are clobbered by the 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // operation. RecordWrite filters out smis so it does not update the 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // write barrier if the value is a smi. 189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordWrite( 19006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register object, Register address, Register value, SaveFPRegsMode save_fp, 191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 19238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org SmiCheck smi_check = INLINE_SMI_CHECK, 19338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value = 19438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org kPointersToHereMaybeInteresting); 195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For page containing |object| mark the region covering the object's map 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // dirty. |object| is the object being stored into, |map| is the Map object 198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // that was stored. 19906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void RecordWriteForMap(Register object, Handle<Map> map, Register scratch1, 20006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register scratch2, SaveFPRegsMode save_fp); 201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Debugger Support 204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DebugBreak(); 206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generates function and stub prologue code. 208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void StubPrologue(); 209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Prologue(bool code_pre_aging); 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Enter specific kind of exit frame. Expects the number of 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // arguments in register eax and sets up the number of arguments in 213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register edi and the pointer to the first argument in register 214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // esi. 21506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void EnterExitFrame(bool save_doubles); 216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EnterApiExitFrame(int argc); 218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Leave the current exit frame. Expects the return value in 220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register eax:edx (untouched) and the pointer to the first 221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // argument in register esi. 22206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void LeaveExitFrame(bool save_doubles); 223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Leave the current exit frame. Expects the return value in 225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register eax (untouched). 226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LeaveApiExitFrame(bool restore_context); 227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Find the function context up the context chain. 229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadContext(Register dst, int context_chain_length); 230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Conditionally load the cached Array transitioned map of type 232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // transitioned_kind from the native context if the map in register 233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // map_in_out is the cached Array map in the native context of 234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // expected_kind. 235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadTransitionedArrayMapConditional( 236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind expected_kind, 237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind transitioned_kind, 238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register map_in_out, 239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* no_map_match); 241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the global function with the given index. 243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadGlobalFunction(int index, Register function); 244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the initial map from the global function. The registers 246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // function and map can be the same. 247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadGlobalFunctionInitialMap(Register function, Register map); 248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push and pop the registers that can hold pointers. 250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PushSafepointRegisters() { pushad(); } 251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PopSafepointRegisters() { popad(); } 252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the value in register/immediate src in the safepoint 253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register stack slot for register dst. 254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void StoreToSafepointRegisterSlot(Register dst, Register src); 255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void StoreToSafepointRegisterSlot(Register dst, Immediate src); 256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadFromSafepointRegisterSlot(Register dst, Register src); 257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadHeapObject(Register result, Handle<HeapObject> object); 259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CmpHeapObject(Register reg, Handle<HeapObject> object); 260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PushHeapObject(Handle<HeapObject> object); 261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadObject(Register result, Handle<Object> object) { 263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllowDeferredHandleDereference heap_object_check; 264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (object->IsHeapObject()) { 265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LoadHeapObject(result, Handle<HeapObject>::cast(object)); 266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Move(result, Immediate(object)); 268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CmpObject(Register reg, Handle<Object> object) { 272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllowDeferredHandleDereference heap_object_check; 273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (object->IsHeapObject()) { 274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CmpHeapObject(reg, Handle<HeapObject>::cast(object)); 275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cmp(reg, Immediate(object)); 277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // JavaScript invokes 282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Invoke the JavaScript function code by either calling or jumping. 284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void InvokeCode(Register code, 285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& expected, 286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& actual, 287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InvokeFlag flag, 288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const CallWrapper& call_wrapper) { 289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InvokeCode(Operand(code), expected, actual, flag, call_wrapper); 290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void InvokeCode(const Operand& code, 293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& expected, 294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& actual, 295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InvokeFlag flag, 296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const CallWrapper& call_wrapper); 297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Invoke the JavaScript function in the given register. Changes the 299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // current context to the context in the function before invoking. 300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void InvokeFunction(Register function, 301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& actual, 302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InvokeFlag flag, 303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const CallWrapper& call_wrapper); 304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void InvokeFunction(Register function, 306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& expected, 307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& actual, 308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InvokeFlag flag, 309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const CallWrapper& call_wrapper); 310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void InvokeFunction(Handle<JSFunction> function, 312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& expected, 313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& actual, 314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InvokeFlag flag, 315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const CallWrapper& call_wrapper); 316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Invoke specified builtin JavaScript function. Adds an entry to 318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the unresolved list if the name does not resolve. 319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void InvokeBuiltin(Builtins::JavaScript id, 320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InvokeFlag flag, 321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const CallWrapper& call_wrapper = NullCallWrapper()); 322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the function for the given builtin in the target register. 324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void GetBuiltinFunction(Register target, Builtins::JavaScript id); 325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the code object for the given builtin in the target register. 327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void GetBuiltinEntry(Register target, Builtins::JavaScript id); 328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Expression support 330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Support for constant splitting. 331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool IsUnsafeImmediate(const Immediate& x); 332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void SafeMove(Register dst, const Immediate& x); 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void SafePush(const Immediate& x); 334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compare object type for heap object. 336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Incoming register is heap_object and outgoing register is map. 337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CmpObjectType(Register heap_object, InstanceType type, Register map); 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compare instance type for map. 340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CmpInstanceType(Register map, InstanceType type); 341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if a map for a JSObject indicates that the object has fast elements. 343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jump to the specified label if it does not. 344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckFastElements(Register map, 345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fail, 346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar); 347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if a map for a JSObject indicates that the object can have both smi 349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // and HeapObject elements. Jump to the specified label if it does not. 350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckFastObjectElements(Register map, 351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fail, 352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar); 353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if a map for a JSObject indicates that the object has fast smi only 355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // elements. Jump to the specified label if it does not. 356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckFastSmiElements(Register map, 357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fail, 358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar); 359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check to see if maybe_number can be stored as a double in 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // FastDoubleElements. If it can, store it at the index specified by key in 362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the FastDoubleElements array elements, otherwise jump to fail. 363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void StoreNumberToDoubleElements(Register maybe_number, 364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register elements, 365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register key, 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fail, 368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = 0); 369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compare an object's map with the specified map. 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CompareMap(Register obj, Handle<Map> map); 372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the map of an object is equal to a specified map and branch to 374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // label if not. Skip the smi check if not required (object is known to be a 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // against maps that are ElementsKind transition maps of the specified map. 377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckMap(Register obj, 378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> map, 379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fail, 380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SmiCheckType smi_check_type); 381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the map of an object is equal to a specified map and branch to a 383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // specified target if equal. Skip the smi check if not required (object is 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // known to be a heap object) 385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DispatchMap(Register obj, 386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register unused, 387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> map, 388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Code> success, 389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SmiCheckType smi_check_type); 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the object in register heap_object is a string. Afterwards the 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register map contains the object map and the register instance_type 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // contains the instance_type. The registers map and instance_type can be the 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // same in which case it contains the instance type afterwards. Either of the 395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // registers map and instance_type can be the same as heap_object. 396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition IsObjectStringType(Register heap_object, 397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register map, 398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register instance_type); 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the object in register heap_object is a name. Afterwards the 401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register map contains the object map and the register instance_type 402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // contains the instance_type. The registers map and instance_type can be the 403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // same in which case it contains the instance type afterwards. Either of the 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // registers map and instance_type can be the same as heap_object. 405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition IsObjectNameType(Register heap_object, 406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register map, 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register instance_type); 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if a heap object's type is in the JSObject range, not including 410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // JSFunction. The object's map will be loaded in the map register. 411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Any or all of the three registers may be the same. 412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The contents of the scratch register will always be overwritten. 413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void IsObjectJSObjectType(Register heap_object, 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register map, 415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fail); 417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The contents of the scratch register will be overwritten. 419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void IsInstanceJSObjectType(Register map, Register scratch, Label* fail); 420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // FCmp is similar to integer cmp, but requires unsigned 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // jcc instructions (je, ja, jae, jb, jbe, je, and jz). 423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void FCmp(); 42406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void FXamMinusZero(); 42506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void FXamSign(); 42606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void X87CheckIA(); 42706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void X87SetRC(int rc); 42879390123903f4a8b6e973f2d4e3743948b97aeb8weiliang.lin@intel.com void X87SetFPUCW(int cw); 429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void ClampUint8(Register reg); 43106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void ClampTOSToUint8(Register result_reg); 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void SlowTruncateToI(Register result_reg, Register input_reg, 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = HeapNumber::kValueOffset - kHeapObjectTag); 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void TruncateHeapNumberToI(Register result_reg, Register input_reg); 437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void TruncateX87TOSToI(Register result_reg); 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87TOSToI(Register result_reg, MinusZeroMode minus_zero_mode, 440b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org Label* lost_precision, Label* is_nan, Label* minus_zero, 441b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org Label::Distance dst = Label::kFar); 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Smi tagging support. 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void SmiTag(Register reg) { 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTag == 0); 446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTagSize == 1); 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org add(reg, reg); 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void SmiUntag(Register reg) { 450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org sar(reg, kSmiTagSize); 451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Modifies the register even if it does not contain a Smi! 454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void SmiUntag(Register reg, Label* is_smi) { 455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTagSize == 1); 456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org sar(reg, kSmiTagSize); 457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTag == 0); 458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org j(not_carry, is_smi); 459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadUint32NoSSE2(Register src); 462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jump the register contains a smi. 464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void JumpIfSmi(Register value, 465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* smi_label, 466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar) { 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org test(value, Immediate(kSmiTagMask)); 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org j(zero, smi_label, distance); 469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jump if the operand is a smi. 471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void JumpIfSmi(Operand value, 472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* smi_label, 473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar) { 474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org test(value, Immediate(kSmiTagMask)); 475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org j(zero, smi_label, distance); 476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jump if register contain a non-smi. 478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void JumpIfNotSmi(Register value, 479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* not_smi_label, 480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar) { 481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org test(value, Immediate(kSmiTagMask)); 482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org j(not_zero, not_smi_label, distance); 483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadInstanceDescriptors(Register map, Register descriptors); 486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EnumLength(Register dst, Register map); 487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void NumberOfOwnDescriptors(Register dst, Register map); 488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org template<typename Field> 490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DecodeField(Register reg) { 491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int shift = Field::kShift; 492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int mask = Field::kMask >> Field::kShift; 493e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org if (shift != 0) { 494e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org sar(reg, shift); 495e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org } 496e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org and_(reg, Immediate(mask)); 497e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org } 498e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 499e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org template<typename Field> 500e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org void DecodeFieldToSmi(Register reg) { 501e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org static const int shift = Field::kShift; 502e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize; 503e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0); 504e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org STATIC_ASSERT(kSmiTag == 0); 505e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org if (shift < kSmiTagSize) { 506e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org shl(reg, kSmiTagSize - shift); 507e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org } else if (shift > kSmiTagSize) { 508e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org sar(reg, shift - kSmiTagSize); 509e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org } 510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org and_(reg, Immediate(mask)); 511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abort execution if argument is not a number, enabled via --debug-code. 514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AssertNumber(Register object); 515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abort execution if argument is not a smi, enabled via --debug-code. 517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AssertSmi(Register object); 518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abort execution if argument is a smi, enabled via --debug-code. 520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AssertNotSmi(Register object); 521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abort execution if argument is not a string, enabled via --debug-code. 523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AssertString(Register object); 524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abort execution if argument is not a name, enabled via --debug-code. 526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AssertName(Register object); 527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abort execution if argument is not undefined or an AllocationSite, enabled 529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // via --debug-code. 530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AssertUndefinedOrAllocationSite(Register object); 531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Exception handling 534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push a new try handler and link it into try handler chain. 536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PushTryHandler(StackHandler::Kind kind, int handler_index); 537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Unlink the stack handler on top of the stack from the try handler chain. 539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PopTryHandler(); 540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Throw to the top handler in the try hander chain. 542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Throw(Register value); 543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Throw past all JS frames to the top JS entry frame. 545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void ThrowUncatchable(Register value); 546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Inline caching support 549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate code for checking access rights - used for security checks 551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // on access to global objects across environments. The holder register 552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is left untouched, but the scratch register is clobbered. 553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckAccessGlobalProxy(Register holder_reg, 554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, 555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch2, 556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* miss); 557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void GetNumberHash(Register r0, Register scratch); 559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadFromNumberDictionary(Label* miss, 561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register elements, 562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register key, 563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register r0, 564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register r1, 565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register r2, 566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result); 567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocation support 571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocate an object in new space or old pointer space. If the given space 573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is exhausted control continues at the gc_required label. The allocated 574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object is returned in result and end of the new object is returned in 575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result_end. The register scratch can be passed as no_reg in which case 576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // an additional object reference will be added to the reloc info. The 577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // returned pointers in result and result_end have not yet been tagged as 578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // heap objects. If result_contains_top_on_entry is true the content of 579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result is known to be the allocation top on entry (could be result_end 580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // from a previous call). If result_contains_top_on_entry is true scratch 581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // should be no_reg as it is never used. 582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Allocate(int object_size, 583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result, 584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result_end, 585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* gc_required, 587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllocationFlags flags); 588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Allocate(int header_size, 590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ScaleFactor element_size, 591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register element_count, 592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegisterValueType element_count_type, 593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result, 594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result_end, 595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* gc_required, 597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllocationFlags flags); 598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Allocate(Register object_size, 600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result, 601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result_end, 602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* gc_required, 604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllocationFlags flags); 605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Undo allocation in new space. The object passed and objects allocated after 607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // it will no longer be allocated. Make sure that no pointers are left to the 608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object(s) no longer allocated as they would be invalid when allocation is 609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // un-done. 610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void UndoAllocationInNewSpace(Register object); 611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocate a heap number in new space with undefined value. The 613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register scratch2 can be passed as no_reg; the others must be 614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // valid registers. Returns tagged pointer in result register, or 615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // jumps to gc_required if new space is full. 616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AllocateHeapNumber(Register result, 617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, 618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch2, 61958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org Label* gc_required, 62058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org MutableMode mode = IMMUTABLE); 621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocate a sequential string. All the header fields of the string object 623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // are initialized. 624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AllocateTwoByteString(Register result, 625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register length, 626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, 627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch2, 628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch3, 629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* gc_required); 630b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org void AllocateOneByteString(Register result, Register length, 631b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register scratch1, Register scratch2, 632b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register scratch3, Label* gc_required); 633b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org void AllocateOneByteString(Register result, int length, Register scratch1, 634b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register scratch2, Label* gc_required); 635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocate a raw cons string object. Only the map field of the result is 637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // initialized. 638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AllocateTwoByteConsString(Register result, 639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, 640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch2, 641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* gc_required); 642b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org void AllocateOneByteConsString(Register result, Register scratch1, 643b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register scratch2, Label* gc_required); 644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocate a raw sliced string object. Only the map field of the result is 646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // initialized. 647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AllocateTwoByteSlicedString(Register result, 648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, 649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch2, 650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* gc_required); 651b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org void AllocateOneByteSlicedString(Register result, Register scratch1, 652b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register scratch2, Label* gc_required); 653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy memory, byte-by-byte, from source to destination. Not optimized for 655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // long or aligned copies. 656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The contents of index and scratch are destroyed. 657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CopyBytes(Register source, 658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register destination, 659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register length, 660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch); 661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Initialize fields with filler values. Fields starting at |start_offset| 663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // not including end_offset are overwritten with the value in |filler|. At 664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the end the loop, |start_offset| takes the value of |end_offset|. 665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void InitializeFieldsWithFiller(Register start_offset, 666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register end_offset, 667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register filler); 668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Support functions. 671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check a boolean-bit of a Smi field. 673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void BooleanBitTest(Register object, int field_offset, int bit_index); 674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if result is zero and op is negative. 676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void NegativeZeroTest(Register result, Register op, Label* then_label); 677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if result is zero and any of op1 and op2 are negative. 679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register scratch is destroyed, and it must be different from op2. 680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void NegativeZeroTest(Register result, Register op1, Register op2, 681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, Label* then_label); 682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Try to get function prototype of a function and puts the value in 684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the result register. Checks that the function really is a 685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // function and jumps to the miss label if the fast checks fail. The 686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // function register will be untouched; the other registers may be 687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // clobbered. 688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void TryGetFunctionPrototype(Register function, 689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result, 690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* miss, 692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool miss_on_bound_function = false); 693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Picks out an array index from the hash field. 695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register use: 696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // hash - holds the index's hash. Clobbered. 697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // index - holds the overwritten index on exit. 698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void IndexFromHash(Register hash, Register index); 699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Runtime calls 702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call a code stub. Generate the code if necessary. 704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); 705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Tail call a code stub (jump). Generate the code if necessary. 707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void TailCallStub(CodeStub* stub); 708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return from a code stub after popping its arguments. 710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void StubReturn(int argc); 711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call a runtime routine. 71306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void CallRuntime(const Runtime::Function* f, int num_arguments, 71406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org SaveFPRegsMode save_doubles = kDontSaveFPRegs); 71506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void CallRuntimeSaveDoubles(Runtime::FunctionId id) { 716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const Runtime::Function* function = Runtime::FunctionForId(id); 71706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org CallRuntime(function, function->nargs, kSaveFPRegs); 718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 71906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 72006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Convenience function: Same as above, but takes the fid instead. 72106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void CallRuntime(Runtime::FunctionId id, int num_arguments, 72206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org SaveFPRegsMode save_doubles = kDontSaveFPRegs) { 72306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles); 724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Convenience function: call an external reference. 727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallExternalReference(ExternalReference ref, int num_arguments); 728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Tail call of a runtime routine (jump). 730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Like JumpToExternalReference, but also takes care of passing the number 731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // of parameters. 732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void TailCallExternalReference(const ExternalReference& ext, 733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int num_arguments, 734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int result_size); 735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Convenience function: tail call a runtime routine (jump). 737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void TailCallRuntime(Runtime::FunctionId fid, 738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int num_arguments, 739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int result_size); 740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Before calling a C-function from generated code, align arguments on stack. 742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // After aligning the frame, arguments must be stored in esp[0], esp[4], 743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // etc., not pushed. The argument count assumes all arguments are word sized. 744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Some compilers/platforms require the stack to be aligned when calling 745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // C++ code. 746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Needs a scratch register to do some arithmetic. This register will be 747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // trashed. 748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PrepareCallCFunction(int num_arguments, Register scratch); 749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Calls a C function and cleans up the space for arguments allocated 751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // by PrepareCallCFunction. The called function is not allowed to trigger a 752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // garbage collection, since that might move the code and invalidate the 753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // return address (unless this is somehow accounted for by the called 754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // function). 755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallCFunction(ExternalReference function, int num_arguments); 756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallCFunction(Register function, int num_arguments); 757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Prepares stack to put arguments (aligns and so on). Reserves 759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // space for return value if needed (assumes the return value is a handle). 760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1) 761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // etc. Saves context (esi). If space was reserved for return value then 762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // stores the pointer to the reserved slot into esi. 763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PrepareCallApiFunction(int argc); 764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Calls an API function. Allocates HandleScope, extracts returned value 766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // from handle and propagates exceptions. Clobbers ebx, edi and 767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // caller-save registers. Restores context. On return removes 768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // stack_space * kPointerSize (GCed). 769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallApiFunctionAndReturn(Register function_address, 770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference thunk_ref, 771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand thunk_last_arg, 772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int stack_space, 773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand return_value_operand, 774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand* context_restore_operand); 775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jump to a runtime routine. 777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void JumpToExternalReference(const ExternalReference& ext); 778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Utilities 781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Ret(); 783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return and drop arguments from stack, where the number of arguments 785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // may be bigger than 2^16 - 1. Requires a scratch register. 786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Ret(int bytes_dropped, Register scratch); 787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit code to discard a non-negative number of pointer-sized elements 789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // from the stack, clobbering only the esp register. 790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Drop(int element_count); 791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Call(Label* target) { call(target); } 793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Push(Register src) { push(src); } 794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Pop(Register dst) { pop(dst); } 795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit call to the code we are currently generating. 797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallSelf() { 798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); 799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org call(self, RelocInfo::CODE_TARGET); 800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Move if the registers are not identical. 803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Move(Register target, Register source); 804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Move a constant into a destination using the most efficient encoding. 806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Move(Register dst, const Immediate& x); 807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Move(const Operand& dst, const Immediate& x); 808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push a handle value. 810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Push(Handle<Object> handle) { push(Immediate(handle)); } 811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); } 812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> CodeObject() { 814e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!code_object_.is_null()); 815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return code_object_; 816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Insert code to verify that the x87 stack has the specified depth (0-7) 819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void VerifyX87StackDepth(uint32_t depth); 820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit code for a truncating division by a constant. The dividend register is 822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // unchanged, the result is in edx, and eax gets clobbered. 823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void TruncatingDiv(Register dividend, int32_t divisor); 824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // StatsCounter support 827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void SetCounter(StatsCounter* counter, int value); 829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void IncrementCounter(StatsCounter* counter, int value); 830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DecrementCounter(StatsCounter* counter, int value); 831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void IncrementCounter(Condition cc, StatsCounter* counter, int value); 832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DecrementCounter(Condition cc, StatsCounter* counter, int value); 833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Debugging 837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Calls Abort(msg) if the condition cc is not satisfied. 839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Use --debug_code to enable. 840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Assert(Condition cc, BailoutReason reason); 841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AssertFastElements(Register elements); 843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Like Assert(), but always enabled. 845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Check(Condition cc, BailoutReason reason); 846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Print a message to stdout and abort execution. 848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Abort(BailoutReason reason); 849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the stack is aligned. 851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckStackAlignment(); 852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Verify restrictions about code generated in stubs. 854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void set_generating_stub(bool value) { generating_stub_ = value; } 855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool generating_stub() { return generating_stub_; } 856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void set_has_frame(bool value) { has_frame_ = value; } 857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool has_frame() { return has_frame_; } 858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline bool AllowThisStubCall(CodeStub* stub); 859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // String utilities. 862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate code to do a lookup in the number string cache. If the number in 864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the register object is found in the cache the generated code falls through 865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // with the result in the result register. The object and the result register 866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // can be the same. If the number is not found in the cache the code jumps to 867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the label not_found with only the content of register object unchanged. 868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LookupNumberStringCache(Register object, 869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result, 870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, 871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch2, 872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* not_found); 873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 874b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // Check whether the instance type represents a flat one-byte string. Jump to 875b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // the label if not. If the instance type can be scratched specify same 876b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // register for both instance type and scratch. 877b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org void JumpIfInstanceTypeIsNotSequentialOneByte( 878b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register instance_type, Register scratch, 879b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Label* on_not_flat_one_byte_string); 880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 881b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // Checks if both objects are sequential one-byte strings, and jumps to label 882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // if either is not. 883b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org void JumpIfNotBothSequentialOneByteStrings( 884b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register object1, Register object2, Register scratch1, Register scratch2, 885b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Label* on_not_flat_one_byte_strings); 886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Checks if the given register or operand is a unique name 88806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name, 88906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label::Distance distance = Label::kFar) { 89006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org JumpIfNotUniqueNameInstanceType(Operand(reg), not_unique_name, distance); 891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 89306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name, 89406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label::Distance distance = Label::kFar); 895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitSeqStringSetCharCheck(Register string, 897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index, 898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value, 899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org uint32_t encoding_mask); 900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static int SafepointRegisterStackIndex(Register reg) { 902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return SafepointRegisterStackIndex(reg.code()); 903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Activation support. 906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EnterFrame(StackFrame::Type type); 907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LeaveFrame(StackFrame::Type type); 908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Expects object in eax and returns map with validated enum cache 910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // in eax. Assumes that any other register can be used as a scratch. 911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CheckEnumCache(Label* call_runtime); 912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // AllocationMemento support. Arrays may have an associated 914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // AllocationMemento object that can be checked for in order to pretransition 915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to another type. 916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // On entry, receiver_reg should point to the array object. 917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // scratch_reg gets clobbered. 918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If allocation info is present, conditional code is set to equal. 919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void TestJSArrayForAllocationMemento(Register receiver_reg, 920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch_reg, 921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* no_memento_found); 922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, 924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch_reg, 925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* memento_found) { 926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_memento_found; 927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TestJSArrayForAllocationMemento(receiver_reg, scratch_reg, 928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &no_memento_found); 929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org j(equal, memento_found); 930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bind(&no_memento_found); 931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jumps to found label if a prototype map has dictionary elements. 934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, 935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1, Label* found); 936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool generating_stub_; 939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool has_frame_; 940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This handle will be patched with the code object on installation. 941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> code_object_; 942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Helper functions for generating invokes. 944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void InvokePrologue(const ParameterCount& expected, 945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ParameterCount& actual, 946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Code> code_constant, 947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const Operand& code_operand, 948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* done, 949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool* definitely_mismatches, 950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InvokeFlag flag, 951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance done_distance, 952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const CallWrapper& call_wrapper = NullCallWrapper()); 953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EnterExitFramePrologue(); 95506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void EnterExitFrameEpilogue(int argc, bool save_doubles); 956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LeaveExitFrameEpilogue(bool restore_context); 958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocation support helpers. 960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadAllocationTopHelper(Register result, 961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllocationFlags flags); 963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void UpdateAllocationTopHelper(Register result_end, 965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllocationFlags flags); 967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. 969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void InNewSpace(Register object, 970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition cc, 972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* condition_met, 973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance condition_met_distance = Label::kFar); 974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Helper for finding the mark bits for an address. Afterwards, the 976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // bitmap register points at the word with the mark bits and the mask 977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the position of the first bit. Uses ecx as scratch and leaves addr_reg 978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // unchanged. 979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void GetMarkBits(Register addr_reg, 980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register bitmap_reg, 981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register mask_reg); 982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Helper for throwing exceptions. Compute a handler address and jump to 984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // it. See the implementation for register usage. 985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void JumpToHandlerEntry(); 986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compute memory operands for safepoint stack slots. 988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand SafepointRegisterSlot(Register reg); 989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static int SafepointRegisterStackIndex(int reg_code); 990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Needs access to SafepointRegisterStackIndex for compiled frame 992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // traversal. 993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class StandardFrame; 994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The code patcher is used to patch (typically) small parts of code e.g. for 998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// debugging and other types of instrumentation. When using the code patcher 999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// the exact number of bytes specified must be emitted. Is not legal to emit 1000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// relocation information. If any of these constraints are violated it causes 1001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// an assertion. 1002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass CodePatcher { 1003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 1004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CodePatcher(byte* address, int size); 1005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org virtual ~CodePatcher(); 1006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Macro assembler to emit code. 1008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MacroAssembler* masm() { return &masm_; } 1009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 1011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* address_; // The address of the code being patched. 1012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int size_; // Number of bytes of the expected patch size. 1013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MacroAssembler masm_; // Macro assembler used to generate the code. 1014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 1015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// ----------------------------------------------------------------------------- 1018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Static helper functions. 1019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generate an Operand for loading a field from an object. 1021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand FieldOperand(Register object, int offset) { 1022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(object, offset - kHeapObjectTag); 1023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generate an Operand for loading an indexed field from an object. 1027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand FieldOperand(Register object, 1028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index, 1029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ScaleFactor scale, 1030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset) { 1031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(object, index, scale, offset - kHeapObjectTag); 1032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand FixedArrayElementOperand(Register array, 1036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index_as_smi, 1037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int additional_offset = 0) { 1038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize; 1039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return FieldOperand(array, index_as_smi, times_half_pointer_size, offset); 1040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand ContextOperand(Register context, int index) { 1044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(context, Context::SlotOffset(index)); 1045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand GlobalObjectOperand() { 1049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX); 1050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generates an Operand for saving parameters after PrepareCallApiFunction. 1054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgOperand ApiParameterOperand(int index); 1055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef GENERATED_CODE_COVERAGE 1058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgextern void LogGeneratedCodeCoverage(const char* file_line); 1059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define CODE_COVERAGE_STRINGIFY(x) #x 1060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 1061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 1062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define ACCESS_MASM(masm) { \ 1063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* ia32_coverage_function = \ 1064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \ 1065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->pushfd(); \ 1066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->pushad(); \ 1067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ 1068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \ 1069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->pop(eax); \ 1070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->popad(); \ 1071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->popfd(); \ 1072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } \ 1073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm-> 1074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#else 1075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define ACCESS_MASM(masm) masm-> 1076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 1077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} } // namespace v8::internal 1080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif // V8_X87_MACRO_ASSEMBLER_X87_H_ 1082