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

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 160453: X64: Reenabled RSet. (Closed)
Patch Set: Created 11 years, 4 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
« src/x64/assembler-x64.h ('K') | « src/x64/ic-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 13 matching lines...) Expand all
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 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "bootstrapper.h" 30 #include "bootstrapper.h"
31 #include "codegen-inl.h" 31 #include "codegen-inl.h"
32 #include "assembler-x64.h" 32 #include "assembler-x64.h"
33 #include "macro-assembler-x64.h" 33 #include "macro-assembler-x64.h"
34 #include "serialize.h"
34 #include "debug.h" 35 #include "debug.h"
35 36
36 namespace v8 { 37 namespace v8 {
37 namespace internal { 38 namespace internal {
38 39
39 MacroAssembler::MacroAssembler(void* buffer, int size) 40 MacroAssembler::MacroAssembler(void* buffer, int size)
40 : Assembler(buffer, size), 41 : Assembler(buffer, size),
41 unresolved_(0), 42 unresolved_(0),
42 generating_stub_(false), 43 generating_stub_(false),
43 allow_stub_calls_(true), 44 allow_stub_calls_(true),
44 code_object_(Heap::undefined_value()) { 45 code_object_(Heap::undefined_value()) {
45 } 46 }
46 47
47 48
48 // TODO(x64): For now, the write barrier is disabled on x64 and we 49
49 // therefore generate no code. This should be fixed when the write 50 static void RecordWriteHelper(MacroAssembler* masm,
50 // barrier is enabled. 51 Register object,
51 void MacroAssembler::RecordWrite(Register object, int offset, 52 Register addr,
52 Register value, Register scratch) { 53 Register scratch) {
54 Label fast;
55
56 // Compute the page address from the heap object pointer, leave it
57 // in 'object'.
58 ASSERT(is_int32(~Page::kPageAlignmentMask));
59 masm->and_(object,
60 Immediate(static_cast<int32_t>(~Page::kPageAlignmentMask)));
61
62 // Compute the bit addr in the remembered set, leave it in "addr".
63 masm->subq(addr, object);
64 masm->shr(addr, Immediate(kPointerSizeLog2));
65
66 // If the bit offset lies beyond the normal remembered set range, it is in
67 // the extra remembered set area of a large object.
68 masm->cmpq(addr, Immediate(Page::kPageSize / kPointerSize));
69 masm->j(less, &fast);
70
71 // Adjust 'addr' to be relative to the start of the extra remembered set
72 // and the page address in 'object' to be the address of the extra
73 // remembered set.
74 masm->subq(addr, Immediate(Page::kPageSize / kPointerSize));
75 // Load the array length into 'scratch'.
76 masm->movl(scratch,
77 Operand(object,
78 Page::kObjectStartOffset + FixedArray::kLengthOffset));
79 // Extra remembered set starts right after FixedArray.
80 // Add the page header, array header, and array body size
81 // (length * pointer size) to the page address to find the extra remembered
82 // set start.
83 masm->lea(object,
84 Operand(object, scratch, times_pointer_size,
85 Page::kObjectStartOffset + FixedArray::kHeaderSize));
86
87 // NOTE: For now, we use the bit-test-and-set (bts) x86 instruction
88 // to limit code size. We should probably evaluate this decision by
89 // measuring the performance of an equivalent implementation using
90 // "simpler" instructions
91 masm->bind(&fast);
92 masm->bts(Operand(object, Page::kRSetOffset), addr);
53 } 93 }
54 94
55 95
96 class RecordWriteStub : public CodeStub {
97 public:
98 RecordWriteStub(Register object, Register addr, Register scratch)
99 : object_(object), addr_(addr), scratch_(scratch) { }
100
101 void Generate(MacroAssembler* masm);
102
103 private:
104 Register object_;
105 Register addr_;
106 Register scratch_;
107
108 #ifdef DEBUG
109 void Print() {
110 PrintF("RecordWriteStub (object reg %d), (addr reg %d), (scratch reg %d)\n",
111 object_.code(), addr_.code(), scratch_.code());
112 }
113 #endif
114
115 // Minor key encoding in 12 bits of three registers (object, address and
116 // scratch) OOOOAAAASSSS.
117 class ScratchBits: public BitField<uint32_t, 0, 4> {};
118 class AddressBits: public BitField<uint32_t, 4, 4> {};
119 class ObjectBits: public BitField<uint32_t, 8, 4> {};
120
121 Major MajorKey() { return RecordWrite; }
122
123 int MinorKey() {
124 // Encode the registers.
125 return ObjectBits::encode(object_.code()) |
126 AddressBits::encode(addr_.code()) |
127 ScratchBits::encode(scratch_.code());
128 }
129 };
130
131
132 void RecordWriteStub::Generate(MacroAssembler* masm) {
133 RecordWriteHelper(masm, object_, addr_, scratch_);
134 masm->ret(0);
135 }
136
137
138 // Set the remembered set bit for [object+offset].
139 // object is the object being stored into, value is the object being stored.
140 // If offset is zero, then the scratch register contains the array index into
141 // the elements array represented as a Smi.
142 // All registers are clobbered by the operation.
143 void MacroAssembler::RecordWrite(Register object,
144 int offset,
145 Register value,
146 Register scratch) {
147 // First, check if a remembered set write is even needed. The tests below
148 // catch stores of Smis and stores into young gen (which does not have space
149 // for the remembered set bits.
150 Label done;
151
152 // This optimization cannot survive serialization and deserialization,
153 // so we disable as long as serialization can take place.
154 intptr_t new_space_start =
155 reinterpret_cast<intptr_t>(
156 ExternalReference::new_space_start().address());
157 if (Serializer::enabled() || new_space_start < 0) {
158 // Cannot do smart bit-twiddling. Need to do two consecutive checks.
159 // Check for Smi first.
160 testl(value, Immediate(kSmiTagMask));
161 j(zero, &done);
William Hesse 2009/08/03 09:03:28 Remove this smi test - we think it isn't worth it.
Lasse Reichstein 2009/08/03 10:45:45 Done.
162 // Test that the object address is not in the new space. We cannot
163 // set remembered set bits in the new space.
164 movq(value, object);
165 ASSERT(is_int32(static_cast<int64_t>(Heap::NewSpaceMask())));
166 and_(value, Immediate(static_cast<int32_t>(Heap::NewSpaceMask())));
167 movq(kScratchRegister, ExternalReference::new_space_start());
168 cmpq(value, kScratchRegister);
169 j(equal, &done);
170 } else {
William Hesse 2009/08/03 09:03:28 This optimization is unsafe if object can be in th
Lasse Reichstein 2009/08/03 10:45:45 Done.
171 // move the value SmiTag into the sign bit
172 ASSERT(kSmiTagSize == 1);
173 ASSERT(kSmiTag == 0);
174 shl(value, Immediate(63));
175
176 // remove the uninteresting bits inside the page
177 movq(kScratchRegister, object);
178 ASSERT(is_int32(static_cast<int64_t>(Heap::NewSpaceMask())));
179 and_(kScratchRegister,
180 Immediate(static_cast<int32_t>(Heap::NewSpaceMask())));
181 // combine the object with value SmiTag
182 or_(value, kScratchRegister);
183 // xor has two effects:
184 // - if the value was a smi, then the result will be negative
185 // - if the object is pointing into new space area the page bits will
186 // all be zero.
187 movq(kScratchRegister, new_space_start | (static_cast<int64_t>(1) << 63),
188 RelocInfo::NONE);
189 xor_(value, kScratchRegister);
190 // Check for both conditions in one branch
191 j(less_equal, &done); // Jump if either zero or sign flag set.
192 }
193
194 if ((offset > 0) && (offset < Page::kMaxHeapObjectSize)) {
195 // Compute the bit offset in the remembered set, leave it in 'value'.
196 movq(value, object);
197 ASSERT(is_uint32(Page::kPageAlignmentMask));
198 and_(value, Immediate(static_cast<uint32_t>(Page::kPageAlignmentMask)));
199 addq(value, Immediate(offset));
200 shr(value, Immediate(kObjectAlignmentBits));
201
202 // Compute the page address from the heap object pointer, leave it in
203 // 'object' (immediate value is sign extended).
204 and_(object, Immediate(~Page::kPageAlignmentMask));
205
206 // NOTE: For now, we use the bit-test-and-set (bts) x86 instruction
207 // to limit code size. We should probably evaluate this decision by
208 // measuring the performance of an equivalent implementation using
209 // "simpler" instructions
210 bts(Operand(object, Page::kRSetOffset), value);
211 } else {
212 Register dst = scratch;
213 if (offset != 0) {
214 lea(dst, Operand(object, offset));
215 } else {
216 // array access: calculate the destination address in the same manner as
217 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 4 to get an offset
218 // into an array of words.
219 lea(dst, Operand(object, dst, times_half_pointer_size,
220 FixedArray::kHeaderSize - kHeapObjectTag));
221 }
222 // If we are already generating a shared stub, not inlining the
223 // record write code isn't going to save us any memory.
224 if (generating_stub()) {
225 RecordWriteHelper(this, object, dst, value);
226 } else {
227 RecordWriteStub stub(object, dst, value);
228 CallStub(&stub);
229 }
230 }
231
232 bind(&done);
233 }
234
235
56 void MacroAssembler::Assert(Condition cc, const char* msg) { 236 void MacroAssembler::Assert(Condition cc, const char* msg) {
57 if (FLAG_debug_code) Check(cc, msg); 237 if (FLAG_debug_code) Check(cc, msg);
58 } 238 }
59 239
60 240
61 void MacroAssembler::Check(Condition cc, const char* msg) { 241 void MacroAssembler::Check(Condition cc, const char* msg) {
62 Label L; 242 Label L;
63 j(cc, &L); 243 j(cc, &L);
64 Abort(msg); 244 Abort(msg);
65 // will not return here 245 // will not return here
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 Context::SECURITY_TOKEN_INDEX * kPointerSize; 1225 Context::SECURITY_TOKEN_INDEX * kPointerSize;
1046 movq(scratch, FieldOperand(scratch, token_offset)); 1226 movq(scratch, FieldOperand(scratch, token_offset));
1047 cmpq(scratch, FieldOperand(kScratchRegister, token_offset)); 1227 cmpq(scratch, FieldOperand(kScratchRegister, token_offset));
1048 j(not_equal, miss); 1228 j(not_equal, miss);
1049 1229
1050 bind(&same_contexts); 1230 bind(&same_contexts);
1051 } 1231 }
1052 1232
1053 1233
1054 } } // namespace v8::internal 1234 } } // namespace v8::internal
OLDNEW
« src/x64/assembler-x64.h ('K') | « src/x64/ic-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698