Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Side by Side Diff: src/ia32/macro-assembler-ia32.h

Issue 7060010: Merge bleeding edge into the GC branch up to 7948. The asserts (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698