| Index: src/ia32/macro-assembler-ia32.h
|
| ===================================================================
|
| --- src/ia32/macro-assembler-ia32.h (revision 7948)
|
| +++ src/ia32/macro-assembler-ia32.h (working copy)
|
| @@ -29,7 +29,7 @@
|
| #define V8_IA32_MACRO_ASSEMBLER_IA32_H_
|
|
|
| #include "assembler.h"
|
| -#include "type-info.h"
|
| +#include "v8globals.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -45,6 +45,7 @@
|
| RESULT_CONTAINS_TOP = 1 << 1
|
| };
|
|
|
| +
|
| // Convenience for platform-independent signatures. We do not normally
|
| // distinguish memory operands from other operands on ia32.
|
| typedef Operand MemOperand;
|
| @@ -81,63 +82,66 @@
|
|
|
| // Check if object is in new space.
|
| // scratch can be object itself, but it will be clobbered.
|
| - template <typename LabelType>
|
| void InNewSpace(Register object,
|
| Register scratch,
|
| Condition cc, // equal for new space, not_equal otherwise.
|
| - LabelType* branch);
|
| + Label* branch,
|
| + Label::Distance branch_distance = Label::kFar);
|
|
|
| - template<typename LabelType>
|
| - void CheckPageFlag(Register object,
|
| - Register scratch,
|
| - MemoryChunk::MemoryChunkFlags flag,
|
| - Condition cc,
|
| - LabelType* condition_met);
|
| + inline void CheckPageFlag(
|
| + Register object,
|
| + Register scratch,
|
| + MemoryChunk::MemoryChunkFlags flag,
|
| + Condition cc,
|
| + Label* condition_met,
|
| + Label::Distance condition_met_distance = Label::kFar);
|
|
|
| // Check if an object has a given incremental marking colour. Also uses ecx!
|
| // The colour bits are found by splitting the address at the bit offset
|
| // indicated by the mask: bits that are zero in the mask are used for the
|
| // address of the bitmap, and bits that are one in the mask are used for the
|
| // index of the bit.
|
| - template <typename LabelType>
|
| - void HasColour(Register object,
|
| - Register scratch0,
|
| - Register scratch1,
|
| - LabelType* has_colour,
|
| - int first_bit,
|
| - int second_bit);
|
| + inline void HasColour(Register object,
|
| + Register scratch0,
|
| + Register scratch1,
|
| + Label* has_colour,
|
| + Label::Distance has_colour_distance,
|
| + int first_bit,
|
| + int second_bit);
|
|
|
| - template <typename LabelType>
|
| - void InOldSpaceIsBlack(Register object,
|
| - Register scratch0,
|
| - Register scratch1,
|
| - LabelType* is_black);
|
| + inline void InOldSpaceIsBlack(
|
| + Register object,
|
| + Register scratch0,
|
| + Register scratch1,
|
| + Label* is_black,
|
| + Label::Distance is_black_distance = Label::kFar);
|
|
|
| - template <typename LabelType>
|
| - void InNewSpaceIsBlack(Register object,
|
| - Register scratch0,
|
| - Register scratch1,
|
| - LabelType* is_black);
|
| + inline void InNewSpaceIsBlack(
|
| + Register object,
|
| + Register scratch0,
|
| + Register scratch1,
|
| + Label* is_black,
|
| + Label::Distance is_black_distance = Label::kFar);
|
|
|
| // Checks the colour of an object. If the object is already grey or black
|
| // then we just fall through, since it is already live. If it is white and
|
| // we can determine that it doesn't need to be scanned, then we just mark it
|
| // black and fall through. For the rest we jump to the label so the
|
| // incremental marker can fix its assumptions.
|
| - template <typename LabelType>
|
| - void EnsureNotWhite(Register object,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - LabelType* object_is_white_and_not_data,
|
| - bool in_new_space);
|
| + inline void EnsureNotWhite(Register object,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Label* object_is_white_and_not_data,
|
| + Label::Distance distance,
|
| + bool in_new_space);
|
|
|
| // Checks whether an object is data-only, ie it does need to be scanned by the
|
| // garbage collector.
|
| - template <typename LabelType>
|
| - void IsDataObject(Register value,
|
| - Register scratch,
|
| - LabelType* not_data_object,
|
| - bool in_new_space);
|
| + inline void IsDataObject(Register value,
|
| + Register scratch,
|
| + Label* not_data_object,
|
| + Label::Distance not_data_object_distance,
|
| + bool in_new_space);
|
|
|
| // Notify the garbage collector that we wrote a pointer into an object.
|
| // |object| is the object being stored into, |value| is the object being
|
| @@ -296,6 +300,11 @@
|
| void Set(Register dst, const Immediate& x);
|
| void Set(const Operand& dst, const Immediate& x);
|
|
|
| + // Support for constant splitting.
|
| + bool IsUnsafeImmediate(const Immediate& x);
|
| + void SafeSet(Register dst, const Immediate& x);
|
| + void SafePush(const Immediate& x);
|
| +
|
| // Compare object type for heap object.
|
| // Incoming register is heap_object and outgoing register is map.
|
| void CmpObjectType(Register heap_object, InstanceType type, Register map);
|
| @@ -303,14 +312,22 @@
|
| // Compare instance type for map.
|
| void CmpInstanceType(Register map, InstanceType type);
|
|
|
| - // Check if the map of an object is equal to a specified map and
|
| - // branch to label if not. Skip the smi check if not required
|
| - // (object is known to be a heap object)
|
| + // Check if the map of an object is equal to a specified map and branch to
|
| + // label if not. Skip the smi check if not required (object is known to be a
|
| + // heap object)
|
| void CheckMap(Register obj,
|
| Handle<Map> map,
|
| Label* fail,
|
| - bool is_heap_object);
|
| + SmiCheckType smi_check_type);
|
|
|
| + // Check if the map of an object is equal to a specified map and branch to a
|
| + // specified target if equal. Skip the smi check if not required (object is
|
| + // known to be a heap object)
|
| + void DispatchMap(Register obj,
|
| + Handle<Map> map,
|
| + Handle<Code> success,
|
| + SmiCheckType smi_check_type);
|
| +
|
| // Check if the object in register heap_object is a string. Afterwards the
|
| // register map contains the object map and the register instance_type
|
| // contains the instance_type. The registers map and instance_type can be the
|
| @@ -336,6 +353,13 @@
|
| // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
|
| void FCmp();
|
|
|
| + void ClampUint8(Register reg);
|
| +
|
| + void ClampDoubleToUint8(XMMRegister input_reg,
|
| + XMMRegister scratch_reg,
|
| + Register result_reg);
|
| +
|
| +
|
| // Smi tagging support.
|
| void SmiTag(Register reg) {
|
| ASSERT(kSmiTag == 0);
|
| @@ -347,16 +371,6 @@
|
| }
|
|
|
| // Modifies the register even if it does not contain a Smi!
|
| - void SmiUntag(Register reg, TypeInfo info, Label* non_smi) {
|
| - ASSERT(kSmiTagSize == 1);
|
| - sar(reg, kSmiTagSize);
|
| - if (info.IsSmi()) {
|
| - ASSERT(kSmiTag == 0);
|
| - j(carry, non_smi);
|
| - }
|
| - }
|
| -
|
| - // Modifies the register even if it does not contain a Smi!
|
| void SmiUntag(Register reg, Label* is_smi) {
|
| ASSERT(kSmiTagSize == 1);
|
| sar(reg, kSmiTagSize);
|
| @@ -367,25 +381,14 @@
|
| // Jump the register contains a smi.
|
| inline void JumpIfSmi(Register value, Label* smi_label) {
|
| test(value, Immediate(kSmiTagMask));
|
| - j(zero, smi_label, not_taken);
|
| + j(zero, smi_label);
|
| }
|
| // Jump if register contain a non-smi.
|
| inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
|
| test(value, Immediate(kSmiTagMask));
|
| - j(not_zero, not_smi_label, not_taken);
|
| + j(not_zero, not_smi_label);
|
| }
|
|
|
| - // Assumes input is a heap object.
|
| - void JumpIfNotNumber(Register reg, TypeInfo info, Label* on_not_number);
|
| -
|
| - // Assumes input is a heap number. Jumps on things out of range. Also jumps
|
| - // on the min negative int32. Ignores frational parts.
|
| - void ConvertToInt32(Register dst,
|
| - Register src, // Can be the same as dst.
|
| - Register scratch, // Can be no_reg or dst, but not src.
|
| - TypeInfo info,
|
| - Label* on_not_int32);
|
| -
|
| void LoadPowerOf2(XMMRegister dst, Register scratch, int power);
|
|
|
| // Abort execution if argument is not a number. Used in debug code.
|
| @@ -749,8 +752,9 @@
|
| const ParameterCount& actual,
|
| Handle<Code> code_constant,
|
| const Operand& code_operand,
|
| - NearLabel* done,
|
| + Label* done,
|
| InvokeFlag flag,
|
| + Label::Distance done_distance,
|
| const CallWrapper& call_wrapper = NullCallWrapper());
|
|
|
| // Activation support.
|
| @@ -793,37 +797,6 @@
|
| };
|
|
|
|
|
| -template <typename LabelType>
|
| -void MacroAssembler::InNewSpace(Register object,
|
| - Register scratch,
|
| - Condition cc,
|
| - LabelType* branch) {
|
| - ASSERT(cc == equal || cc == not_equal);
|
| - if (Serializer::enabled()) {
|
| - // Can't do arithmetic on external references if it might get serialized.
|
| - Move(scratch, object);
|
| - // The mask isn't really an address. We load it as an external reference in
|
| - // case the size of the new space is different between the snapshot maker
|
| - // and the running system.
|
| - and_(Operand(scratch),
|
| - Immediate(ExternalReference::new_space_mask(isolate())));
|
| - cmp(Operand(scratch),
|
| - Immediate(ExternalReference::new_space_start(isolate())));
|
| - j(cc, branch);
|
| - } else {
|
| - int32_t new_space_start = reinterpret_cast<int32_t>(
|
| - ExternalReference::new_space_start(isolate()).address());
|
| - if (object.is(scratch)) {
|
| - sub(Operand(scratch), Immediate(new_space_start));
|
| - } else {
|
| - lea(scratch, Operand(object, -new_space_start));
|
| - }
|
| - and_(scratch, isolate()->heap()->NewSpaceMask());
|
| - j(cc, branch);
|
| - }
|
| -}
|
| -
|
| -
|
| // The code patcher is used to patch (typically) small parts of code e.g. for
|
| // debugging and other types of instrumentation. When using the code patcher
|
| // the exact number of bytes specified must be emitted. Is not legal to emit
|
|
|