| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 28 #ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
| 29 #define V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 29 #define V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
| 30 | 30 |
| 31 #include "assembler.h" | 31 #include "assembler.h" |
| 32 #include "type-info.h" | 32 #include "v8globals.h" |
| 33 | 33 |
| 34 namespace v8 { | 34 namespace v8 { |
| 35 namespace internal { | 35 namespace internal { |
| 36 | 36 |
| 37 // Flags used for the AllocateInNewSpace functions. | 37 // Flags used for the AllocateInNewSpace functions. |
| 38 enum AllocationFlags { | 38 enum AllocationFlags { |
| 39 // No special flags. | 39 // No special flags. |
| 40 NO_ALLOCATION_FLAGS = 0, | 40 NO_ALLOCATION_FLAGS = 0, |
| 41 // Return the pointer to the allocated already tagged as a heap object. | 41 // Return the pointer to the allocated already tagged as a heap object. |
| 42 TAG_OBJECT = 1 << 0, | 42 TAG_OBJECT = 1 << 0, |
| 43 // The content of the result register already contains the allocation top in | 43 // The content of the result register already contains the allocation top in |
| 44 // new space. | 44 // new space. |
| 45 RESULT_CONTAINS_TOP = 1 << 1 | 45 RESULT_CONTAINS_TOP = 1 << 1 |
| 46 }; | 46 }; |
| 47 | 47 |
| 48 |
| 48 // Convenience for platform-independent signatures. We do not normally | 49 // Convenience for platform-independent signatures. We do not normally |
| 49 // distinguish memory operands from other operands on ia32. | 50 // distinguish memory operands from other operands on ia32. |
| 50 typedef Operand MemOperand; | 51 typedef Operand MemOperand; |
| 51 | 52 |
| 52 enum EmitRememberedSet { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; | 53 enum EmitRememberedSet { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; |
| 53 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; | 54 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; |
| 54 | 55 |
| 55 | 56 |
| 56 bool Aliasing(Register r1, Register r2, Register r3, Register r4); | 57 bool Aliasing(Register r1, Register r2, Register r3, Register r4); |
| 57 | 58 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 74 | 75 |
| 75 // For page containing |object| mark region covering |addr| dirty. | 76 // For page containing |object| mark region covering |addr| dirty. |
| 76 // RememberedSetHelper only works if the object is not in new | 77 // RememberedSetHelper only works if the object is not in new |
| 77 // space. | 78 // space. |
| 78 void RememberedSetHelper(Register addr, | 79 void RememberedSetHelper(Register addr, |
| 79 Register scratch, | 80 Register scratch, |
| 80 SaveFPRegsMode save_fp); | 81 SaveFPRegsMode save_fp); |
| 81 | 82 |
| 82 // Check if object is in new space. | 83 // Check if object is in new space. |
| 83 // scratch can be object itself, but it will be clobbered. | 84 // scratch can be object itself, but it will be clobbered. |
| 84 template <typename LabelType> | |
| 85 void InNewSpace(Register object, | 85 void InNewSpace(Register object, |
| 86 Register scratch, | 86 Register scratch, |
| 87 Condition cc, // equal for new space, not_equal otherwise. | 87 Condition cc, // equal for new space, not_equal otherwise. |
| 88 LabelType* branch); | 88 Label* branch, |
| 89 Label::Distance branch_distance = Label::kFar); |
| 89 | 90 |
| 90 template<typename LabelType> | 91 inline void CheckPageFlag( |
| 91 void CheckPageFlag(Register object, | 92 Register object, |
| 92 Register scratch, | 93 Register scratch, |
| 93 MemoryChunk::MemoryChunkFlags flag, | 94 MemoryChunk::MemoryChunkFlags flag, |
| 94 Condition cc, | 95 Condition cc, |
| 95 LabelType* condition_met); | 96 Label* condition_met, |
| 97 Label::Distance condition_met_distance = Label::kFar); |
| 96 | 98 |
| 97 // Check if an object has a given incremental marking colour. Also uses ecx! | 99 // Check if an object has a given incremental marking colour. Also uses ecx! |
| 98 // The colour bits are found by splitting the address at the bit offset | 100 // The colour bits are found by splitting the address at the bit offset |
| 99 // indicated by the mask: bits that are zero in the mask are used for the | 101 // indicated by the mask: bits that are zero in the mask are used for the |
| 100 // address of the bitmap, and bits that are one in the mask are used for the | 102 // address of the bitmap, and bits that are one in the mask are used for the |
| 101 // index of the bit. | 103 // index of the bit. |
| 102 template <typename LabelType> | 104 inline void HasColour(Register object, |
| 103 void HasColour(Register object, | 105 Register scratch0, |
| 104 Register scratch0, | 106 Register scratch1, |
| 105 Register scratch1, | 107 Label* has_colour, |
| 106 LabelType* has_colour, | 108 Label::Distance has_colour_distance, |
| 107 int first_bit, | 109 int first_bit, |
| 108 int second_bit); | 110 int second_bit); |
| 109 | 111 |
| 110 template <typename LabelType> | 112 inline void InOldSpaceIsBlack( |
| 111 void InOldSpaceIsBlack(Register object, | 113 Register object, |
| 112 Register scratch0, | 114 Register scratch0, |
| 113 Register scratch1, | 115 Register scratch1, |
| 114 LabelType* is_black); | 116 Label* is_black, |
| 117 Label::Distance is_black_distance = Label::kFar); |
| 115 | 118 |
| 116 template <typename LabelType> | 119 inline void InNewSpaceIsBlack( |
| 117 void InNewSpaceIsBlack(Register object, | 120 Register object, |
| 118 Register scratch0, | 121 Register scratch0, |
| 119 Register scratch1, | 122 Register scratch1, |
| 120 LabelType* is_black); | 123 Label* is_black, |
| 124 Label::Distance is_black_distance = Label::kFar); |
| 121 | 125 |
| 122 // Checks the colour of an object. If the object is already grey or black | 126 // Checks the colour of an object. If the object is already grey or black |
| 123 // then we just fall through, since it is already live. If it is white and | 127 // then we just fall through, since it is already live. If it is white and |
| 124 // we can determine that it doesn't need to be scanned, then we just mark it | 128 // we can determine that it doesn't need to be scanned, then we just mark it |
| 125 // black and fall through. For the rest we jump to the label so the | 129 // black and fall through. For the rest we jump to the label so the |
| 126 // incremental marker can fix its assumptions. | 130 // incremental marker can fix its assumptions. |
| 127 template <typename LabelType> | 131 inline void EnsureNotWhite(Register object, |
| 128 void EnsureNotWhite(Register object, | 132 Register scratch1, |
| 129 Register scratch1, | 133 Register scratch2, |
| 130 Register scratch2, | 134 Label* object_is_white_and_not_data, |
| 131 LabelType* object_is_white_and_not_data, | 135 Label::Distance distance, |
| 132 bool in_new_space); | 136 bool in_new_space); |
| 133 | 137 |
| 134 // Checks whether an object is data-only, ie it does need to be scanned by the | 138 // Checks whether an object is data-only, ie it does need to be scanned by the |
| 135 // garbage collector. | 139 // garbage collector. |
| 136 template <typename LabelType> | 140 inline void IsDataObject(Register value, |
| 137 void IsDataObject(Register value, | 141 Register scratch, |
| 138 Register scratch, | 142 Label* not_data_object, |
| 139 LabelType* not_data_object, | 143 Label::Distance not_data_object_distance, |
| 140 bool in_new_space); | 144 bool in_new_space); |
| 141 | 145 |
| 142 // Notify the garbage collector that we wrote a pointer into an object. | 146 // Notify the garbage collector that we wrote a pointer into an object. |
| 143 // |object| is the object being stored into, |value| is the object being | 147 // |object| is the object being stored into, |value| is the object being |
| 144 // stored. All registers are clobbered by the operation. RecordWriteField | 148 // stored. All registers are clobbered by the operation. RecordWriteField |
| 145 // filters out smis so it does not update the write barrier if the value is a | 149 // filters out smis so it does not update the write barrier if the value is a |
| 146 // smi. The offset is the offset from the start of the object, not the offset | 150 // smi. The offset is the offset from the start of the object, not the offset |
| 147 // from the tagged HeapObject pointer. For use with FieldOperand(reg, off). | 151 // from the tagged HeapObject pointer. For use with FieldOperand(reg, off). |
| 148 void RecordWriteField( | 152 void RecordWriteField( |
| 149 Register object, | 153 Register object, |
| 150 int offset, | 154 int offset, |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 // Store the function for the given builtin in the target register. | 293 // Store the function for the given builtin in the target register. |
| 290 void GetBuiltinFunction(Register target, Builtins::JavaScript id); | 294 void GetBuiltinFunction(Register target, Builtins::JavaScript id); |
| 291 | 295 |
| 292 // Store the code object for the given builtin in the target register. | 296 // Store the code object for the given builtin in the target register. |
| 293 void GetBuiltinEntry(Register target, Builtins::JavaScript id); | 297 void GetBuiltinEntry(Register target, Builtins::JavaScript id); |
| 294 | 298 |
| 295 // Expression support | 299 // Expression support |
| 296 void Set(Register dst, const Immediate& x); | 300 void Set(Register dst, const Immediate& x); |
| 297 void Set(const Operand& dst, const Immediate& x); | 301 void Set(const Operand& dst, const Immediate& x); |
| 298 | 302 |
| 303 // Support for constant splitting. |
| 304 bool IsUnsafeImmediate(const Immediate& x); |
| 305 void SafeSet(Register dst, const Immediate& x); |
| 306 void SafePush(const Immediate& x); |
| 307 |
| 299 // Compare object type for heap object. | 308 // Compare object type for heap object. |
| 300 // Incoming register is heap_object and outgoing register is map. | 309 // Incoming register is heap_object and outgoing register is map. |
| 301 void CmpObjectType(Register heap_object, InstanceType type, Register map); | 310 void CmpObjectType(Register heap_object, InstanceType type, Register map); |
| 302 | 311 |
| 303 // Compare instance type for map. | 312 // Compare instance type for map. |
| 304 void CmpInstanceType(Register map, InstanceType type); | 313 void CmpInstanceType(Register map, InstanceType type); |
| 305 | 314 |
| 306 // Check if the map of an object is equal to a specified map and | 315 // Check if the map of an object is equal to a specified map and branch to |
| 307 // branch to label if not. Skip the smi check if not required | 316 // label if not. Skip the smi check if not required (object is known to be a |
| 308 // (object is known to be a heap object) | 317 // heap object) |
| 309 void CheckMap(Register obj, | 318 void CheckMap(Register obj, |
| 310 Handle<Map> map, | 319 Handle<Map> map, |
| 311 Label* fail, | 320 Label* fail, |
| 312 bool is_heap_object); | 321 SmiCheckType smi_check_type); |
| 322 |
| 323 // Check if the map of an object is equal to a specified map and branch to a |
| 324 // specified target if equal. Skip the smi check if not required (object is |
| 325 // known to be a heap object) |
| 326 void DispatchMap(Register obj, |
| 327 Handle<Map> map, |
| 328 Handle<Code> success, |
| 329 SmiCheckType smi_check_type); |
| 313 | 330 |
| 314 // Check if the object in register heap_object is a string. Afterwards the | 331 // Check if the object in register heap_object is a string. Afterwards the |
| 315 // register map contains the object map and the register instance_type | 332 // register map contains the object map and the register instance_type |
| 316 // contains the instance_type. The registers map and instance_type can be the | 333 // contains the instance_type. The registers map and instance_type can be the |
| 317 // same in which case it contains the instance type afterwards. Either of the | 334 // same in which case it contains the instance type afterwards. Either of the |
| 318 // registers map and instance_type can be the same as heap_object. | 335 // registers map and instance_type can be the same as heap_object. |
| 319 Condition IsObjectStringType(Register heap_object, | 336 Condition IsObjectStringType(Register heap_object, |
| 320 Register map, | 337 Register map, |
| 321 Register instance_type); | 338 Register instance_type); |
| 322 | 339 |
| 323 // Check if a heap object's type is in the JSObject range, not including | 340 // Check if a heap object's type is in the JSObject range, not including |
| 324 // JSFunction. The object's map will be loaded in the map register. | 341 // JSFunction. The object's map will be loaded in the map register. |
| 325 // Any or all of the three registers may be the same. | 342 // Any or all of the three registers may be the same. |
| 326 // The contents of the scratch register will always be overwritten. | 343 // The contents of the scratch register will always be overwritten. |
| 327 void IsObjectJSObjectType(Register heap_object, | 344 void IsObjectJSObjectType(Register heap_object, |
| 328 Register map, | 345 Register map, |
| 329 Register scratch, | 346 Register scratch, |
| 330 Label* fail); | 347 Label* fail); |
| 331 | 348 |
| 332 // The contents of the scratch register will be overwritten. | 349 // The contents of the scratch register will be overwritten. |
| 333 void IsInstanceJSObjectType(Register map, Register scratch, Label* fail); | 350 void IsInstanceJSObjectType(Register map, Register scratch, Label* fail); |
| 334 | 351 |
| 335 // FCmp is similar to integer cmp, but requires unsigned | 352 // FCmp is similar to integer cmp, but requires unsigned |
| 336 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). | 353 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). |
| 337 void FCmp(); | 354 void FCmp(); |
| 338 | 355 |
| 356 void ClampUint8(Register reg); |
| 357 |
| 358 void ClampDoubleToUint8(XMMRegister input_reg, |
| 359 XMMRegister scratch_reg, |
| 360 Register result_reg); |
| 361 |
| 362 |
| 339 // Smi tagging support. | 363 // Smi tagging support. |
| 340 void SmiTag(Register reg) { | 364 void SmiTag(Register reg) { |
| 341 ASSERT(kSmiTag == 0); | 365 ASSERT(kSmiTag == 0); |
| 342 ASSERT(kSmiTagSize == 1); | 366 ASSERT(kSmiTagSize == 1); |
| 343 add(reg, Operand(reg)); | 367 add(reg, Operand(reg)); |
| 344 } | 368 } |
| 345 void SmiUntag(Register reg) { | 369 void SmiUntag(Register reg) { |
| 346 sar(reg, kSmiTagSize); | 370 sar(reg, kSmiTagSize); |
| 347 } | 371 } |
| 348 | 372 |
| 349 // Modifies the register even if it does not contain a Smi! | 373 // Modifies the register even if it does not contain a Smi! |
| 350 void SmiUntag(Register reg, TypeInfo info, Label* non_smi) { | |
| 351 ASSERT(kSmiTagSize == 1); | |
| 352 sar(reg, kSmiTagSize); | |
| 353 if (info.IsSmi()) { | |
| 354 ASSERT(kSmiTag == 0); | |
| 355 j(carry, non_smi); | |
| 356 } | |
| 357 } | |
| 358 | |
| 359 // Modifies the register even if it does not contain a Smi! | |
| 360 void SmiUntag(Register reg, Label* is_smi) { | 374 void SmiUntag(Register reg, Label* is_smi) { |
| 361 ASSERT(kSmiTagSize == 1); | 375 ASSERT(kSmiTagSize == 1); |
| 362 sar(reg, kSmiTagSize); | 376 sar(reg, kSmiTagSize); |
| 363 ASSERT(kSmiTag == 0); | 377 ASSERT(kSmiTag == 0); |
| 364 j(not_carry, is_smi); | 378 j(not_carry, is_smi); |
| 365 } | 379 } |
| 366 | 380 |
| 367 // Jump the register contains a smi. | 381 // Jump the register contains a smi. |
| 368 inline void JumpIfSmi(Register value, Label* smi_label) { | 382 inline void JumpIfSmi(Register value, Label* smi_label) { |
| 369 test(value, Immediate(kSmiTagMask)); | 383 test(value, Immediate(kSmiTagMask)); |
| 370 j(zero, smi_label, not_taken); | 384 j(zero, smi_label); |
| 371 } | 385 } |
| 372 // Jump if register contain a non-smi. | 386 // Jump if register contain a non-smi. |
| 373 inline void JumpIfNotSmi(Register value, Label* not_smi_label) { | 387 inline void JumpIfNotSmi(Register value, Label* not_smi_label) { |
| 374 test(value, Immediate(kSmiTagMask)); | 388 test(value, Immediate(kSmiTagMask)); |
| 375 j(not_zero, not_smi_label, not_taken); | 389 j(not_zero, not_smi_label); |
| 376 } | 390 } |
| 377 | 391 |
| 378 // Assumes input is a heap object. | |
| 379 void JumpIfNotNumber(Register reg, TypeInfo info, Label* on_not_number); | |
| 380 | |
| 381 // Assumes input is a heap number. Jumps on things out of range. Also jumps | |
| 382 // on the min negative int32. Ignores frational parts. | |
| 383 void ConvertToInt32(Register dst, | |
| 384 Register src, // Can be the same as dst. | |
| 385 Register scratch, // Can be no_reg or dst, but not src. | |
| 386 TypeInfo info, | |
| 387 Label* on_not_int32); | |
| 388 | |
| 389 void LoadPowerOf2(XMMRegister dst, Register scratch, int power); | 392 void LoadPowerOf2(XMMRegister dst, Register scratch, int power); |
| 390 | 393 |
| 391 // Abort execution if argument is not a number. Used in debug code. | 394 // Abort execution if argument is not a number. Used in debug code. |
| 392 void AbortIfNotNumber(Register object); | 395 void AbortIfNotNumber(Register object); |
| 393 | 396 |
| 394 // Abort execution if argument is not a smi. Used in debug code. | 397 // Abort execution if argument is not a smi. Used in debug code. |
| 395 void AbortIfNotSmi(Register object); | 398 void AbortIfNotSmi(Register object); |
| 396 | 399 |
| 397 // Abort execution if argument is a smi. Used in debug code. | 400 // Abort execution if argument is a smi. Used in debug code. |
| 398 void AbortIfSmi(Register object); | 401 void AbortIfSmi(Register object); |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 bool generating_stub_; | 745 bool generating_stub_; |
| 743 bool allow_stub_calls_; | 746 bool allow_stub_calls_; |
| 744 // This handle will be patched with the code object on installation. | 747 // This handle will be patched with the code object on installation. |
| 745 Handle<Object> code_object_; | 748 Handle<Object> code_object_; |
| 746 | 749 |
| 747 // Helper functions for generating invokes. | 750 // Helper functions for generating invokes. |
| 748 void InvokePrologue(const ParameterCount& expected, | 751 void InvokePrologue(const ParameterCount& expected, |
| 749 const ParameterCount& actual, | 752 const ParameterCount& actual, |
| 750 Handle<Code> code_constant, | 753 Handle<Code> code_constant, |
| 751 const Operand& code_operand, | 754 const Operand& code_operand, |
| 752 NearLabel* done, | 755 Label* done, |
| 753 InvokeFlag flag, | 756 InvokeFlag flag, |
| 757 Label::Distance done_distance, |
| 754 const CallWrapper& call_wrapper = NullCallWrapper()); | 758 const CallWrapper& call_wrapper = NullCallWrapper()); |
| 755 | 759 |
| 756 // Activation support. | 760 // Activation support. |
| 757 void EnterFrame(StackFrame::Type type); | 761 void EnterFrame(StackFrame::Type type); |
| 758 void LeaveFrame(StackFrame::Type type); | 762 void LeaveFrame(StackFrame::Type type); |
| 759 | 763 |
| 760 void EnterExitFramePrologue(); | 764 void EnterExitFramePrologue(); |
| 761 void EnterExitFrameEpilogue(int argc, bool save_doubles); | 765 void EnterExitFrameEpilogue(int argc, bool save_doubles); |
| 762 | 766 |
| 763 void LeaveExitFrameEpilogue(); | 767 void LeaveExitFrameEpilogue(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 786 // Compute memory operands for safepoint stack slots. | 790 // Compute memory operands for safepoint stack slots. |
| 787 Operand SafepointRegisterSlot(Register reg); | 791 Operand SafepointRegisterSlot(Register reg); |
| 788 static int SafepointRegisterStackIndex(int reg_code); | 792 static int SafepointRegisterStackIndex(int reg_code); |
| 789 | 793 |
| 790 // Needs access to SafepointRegisterStackIndex for optimized frame | 794 // Needs access to SafepointRegisterStackIndex for optimized frame |
| 791 // traversal. | 795 // traversal. |
| 792 friend class OptimizedFrame; | 796 friend class OptimizedFrame; |
| 793 }; | 797 }; |
| 794 | 798 |
| 795 | 799 |
| 796 template <typename LabelType> | |
| 797 void MacroAssembler::InNewSpace(Register object, | |
| 798 Register scratch, | |
| 799 Condition cc, | |
| 800 LabelType* branch) { | |
| 801 ASSERT(cc == equal || cc == not_equal); | |
| 802 if (Serializer::enabled()) { | |
| 803 // Can't do arithmetic on external references if it might get serialized. | |
| 804 Move(scratch, object); | |
| 805 // The mask isn't really an address. We load it as an external reference in | |
| 806 // case the size of the new space is different between the snapshot maker | |
| 807 // and the running system. | |
| 808 and_(Operand(scratch), | |
| 809 Immediate(ExternalReference::new_space_mask(isolate()))); | |
| 810 cmp(Operand(scratch), | |
| 811 Immediate(ExternalReference::new_space_start(isolate()))); | |
| 812 j(cc, branch); | |
| 813 } else { | |
| 814 int32_t new_space_start = reinterpret_cast<int32_t>( | |
| 815 ExternalReference::new_space_start(isolate()).address()); | |
| 816 if (object.is(scratch)) { | |
| 817 sub(Operand(scratch), Immediate(new_space_start)); | |
| 818 } else { | |
| 819 lea(scratch, Operand(object, -new_space_start)); | |
| 820 } | |
| 821 and_(scratch, isolate()->heap()->NewSpaceMask()); | |
| 822 j(cc, branch); | |
| 823 } | |
| 824 } | |
| 825 | |
| 826 | |
| 827 // The code patcher is used to patch (typically) small parts of code e.g. for | 800 // The code patcher is used to patch (typically) small parts of code e.g. for |
| 828 // debugging and other types of instrumentation. When using the code patcher | 801 // debugging and other types of instrumentation. When using the code patcher |
| 829 // the exact number of bytes specified must be emitted. Is not legal to emit | 802 // the exact number of bytes specified must be emitted. Is not legal to emit |
| 830 // relocation information. If any of these constraints are violated it causes | 803 // relocation information. If any of these constraints are violated it causes |
| 831 // an assertion. | 804 // an assertion. |
| 832 class CodePatcher { | 805 class CodePatcher { |
| 833 public: | 806 public: |
| 834 CodePatcher(byte* address, int size); | 807 CodePatcher(byte* address, int size); |
| 835 virtual ~CodePatcher(); | 808 virtual ~CodePatcher(); |
| 836 | 809 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 } \ | 867 } \ |
| 895 masm-> | 868 masm-> |
| 896 #else | 869 #else |
| 897 #define ACCESS_MASM(masm) masm-> | 870 #define ACCESS_MASM(masm) masm-> |
| 898 #endif | 871 #endif |
| 899 | 872 |
| 900 | 873 |
| 901 } } // namespace v8::internal | 874 } } // namespace v8::internal |
| 902 | 875 |
| 903 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 876 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
| OLD | NEW |