OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
9 | 9 |
10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. | 154 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. |
155 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. | 155 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. |
156 __ testq(RCX, Immediate(kSmiTagMask)); | 156 __ testq(RCX, Immediate(kSmiTagMask)); |
157 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 157 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
158 // Range check. | 158 // Range check. |
159 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); | 159 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); |
160 // Runtime throws exception. | 160 // Runtime throws exception. |
161 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 161 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
162 // Note that RBX is Smi, i.e, times 2. | 162 // Note that RBX is Smi, i.e, times 2. |
163 ASSERT(kSmiTagShift == 1); | 163 ASSERT(kSmiTagShift == 1); |
164 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, sizeof(RawArray))); | 164 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset())); |
165 __ ret(); | 165 __ ret(); |
166 __ Bind(&fall_through); | 166 __ Bind(&fall_through); |
167 return false; | 167 return false; |
168 } | 168 } |
169 | 169 |
170 | 170 |
171 bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { | 171 bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { |
172 return Array_getIndexed(assembler); | 172 return Array_getIndexed(assembler); |
173 } | 173 } |
174 | 174 |
175 | 175 |
176 bool Intrinsifier::Array_setIndexed(Assembler* assembler) { | 176 bool Intrinsifier::Array_setIndexed(Assembler* assembler) { |
177 if (FLAG_enable_type_checks) { | 177 if (FLAG_enable_type_checks) { |
178 return false; | 178 return false; |
179 } | 179 } |
180 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. | 180 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. |
181 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. | 181 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. |
182 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array. | 182 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array. |
183 Label fall_through; | 183 Label fall_through; |
184 __ testq(RCX, Immediate(kSmiTagMask)); | 184 __ testq(RCX, Immediate(kSmiTagMask)); |
185 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 185 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
186 // Range check. | 186 // Range check. |
187 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); | 187 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); |
188 // Runtime throws exception. | 188 // Runtime throws exception. |
189 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 189 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
190 // Note that RBX is Smi, i.e, times 2. | 190 // Note that RBX is Smi, i.e, times 2. |
191 ASSERT(kSmiTagShift == 1); | 191 ASSERT(kSmiTagShift == 1); |
192 // Destroy RCX as we will not continue in the function. | 192 // Destroy RCX as we will not continue in the function. |
193 __ StoreIntoObject(RAX, | 193 __ StoreIntoObject(RAX, |
194 FieldAddress(RAX, RCX, TIMES_4, sizeof(RawArray)), | 194 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()), |
195 RDX); | 195 RDX); |
196 // Caller is responsible of preserving the value if necessary. | 196 // Caller is responsible of preserving the value if necessary. |
197 __ ret(); | 197 __ ret(); |
198 __ Bind(&fall_through); | 198 __ Bind(&fall_through); |
199 return false; | 199 return false; |
200 } | 200 } |
201 | 201 |
202 | 202 |
203 // Allocate a GrowableObjectArray using the backing array specified. | 203 // Allocate a GrowableObjectArray using the backing array specified. |
204 // On stack: type argument (+2), data (+1), return-address (+0). | 204 // On stack: type argument (+2), data (+1), return-address (+0). |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 __ testq(RCX, Immediate(kSmiTagMask)); | 297 __ testq(RCX, Immediate(kSmiTagMask)); |
298 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 298 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
299 // Range check using _length field. | 299 // Range check using _length field. |
300 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); | 300 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); |
301 // Runtime throws exception. | 301 // Runtime throws exception. |
302 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 302 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
303 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. | 303 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. |
304 | 304 |
305 // Note that RCX is Smi, i.e, times 4. | 305 // Note that RCX is Smi, i.e, times 4. |
306 ASSERT(kSmiTagShift == 1); | 306 ASSERT(kSmiTagShift == 1); |
307 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, sizeof(RawArray))); | 307 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset())); |
308 __ ret(); | 308 __ ret(); |
309 __ Bind(&fall_through); | 309 __ Bind(&fall_through); |
310 return false; | 310 return false; |
311 } | 311 } |
312 | 312 |
313 | 313 |
314 // Set value into growable object array at specified index. | 314 // Set value into growable object array at specified index. |
315 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). | 315 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). |
316 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { | 316 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { |
317 if (FLAG_enable_type_checks) { | 317 if (FLAG_enable_type_checks) { |
318 return false; | 318 return false; |
319 } | 319 } |
320 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. | 320 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. |
321 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. | 321 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. |
322 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // GrowableArray. | 322 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // GrowableArray. |
323 Label fall_through; | 323 Label fall_through; |
324 __ testq(RCX, Immediate(kSmiTagMask)); | 324 __ testq(RCX, Immediate(kSmiTagMask)); |
325 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 325 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
326 // Range check using _length field. | 326 // Range check using _length field. |
327 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); | 327 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); |
328 // Runtime throws exception. | 328 // Runtime throws exception. |
329 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 329 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
330 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. | 330 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. |
331 // Note that RCX is Smi, i.e, times 4. | 331 // Note that RCX is Smi, i.e, times 4. |
332 ASSERT(kSmiTagShift == 1); | 332 ASSERT(kSmiTagShift == 1); |
333 __ StoreIntoObject(RAX, | 333 __ StoreIntoObject(RAX, |
334 FieldAddress(RAX, RCX, TIMES_4, sizeof(RawArray)), | 334 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()), |
335 RDX); | 335 RDX); |
336 __ ret(); | 336 __ ret(); |
337 __ Bind(&fall_through); | 337 __ Bind(&fall_through); |
338 return false; | 338 return false; |
339 } | 339 } |
340 | 340 |
341 | 341 |
342 // Set length of growable object array. | 342 // Set length of growable object array. |
343 // On stack: growable array (+2), length (+1), return-address (+0). | 343 // On stack: growable array (+2), length (+1), return-address (+0). |
344 bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) { | 344 bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 // RDX: data. | 393 // RDX: data. |
394 // Compare length with capacity. | 394 // Compare length with capacity. |
395 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset())); | 395 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset())); |
396 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Must grow data. | 396 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Must grow data. |
397 const Immediate value_one = Immediate(reinterpret_cast<int64_t>(Smi::New(1))); | 397 const Immediate value_one = Immediate(reinterpret_cast<int64_t>(Smi::New(1))); |
398 // len = len + 1; | 398 // len = len + 1; |
399 __ addq(FieldAddress(RAX, GrowableObjectArray::length_offset()), value_one); | 399 __ addq(FieldAddress(RAX, GrowableObjectArray::length_offset()), value_one); |
400 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Value | 400 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Value |
401 ASSERT(kSmiTagShift == 1); | 401 ASSERT(kSmiTagShift == 1); |
402 __ StoreIntoObject(RDX, | 402 __ StoreIntoObject(RDX, |
403 FieldAddress(RDX, RCX, TIMES_4, sizeof(RawArray)), | 403 FieldAddress(RDX, RCX, TIMES_4, Array::data_offset()), |
404 RAX); | 404 RAX); |
405 const Immediate raw_null = | 405 const Immediate raw_null = |
406 Immediate(reinterpret_cast<int64_t>(Object::null())); | 406 Immediate(reinterpret_cast<int64_t>(Object::null())); |
407 __ movq(RAX, raw_null); | 407 __ movq(RAX, raw_null); |
408 __ ret(); | 408 __ ret(); |
409 __ Bind(&fall_through); | 409 __ Bind(&fall_through); |
410 return false; | 410 return false; |
411 } | 411 } |
412 | 412 |
413 | 413 |
(...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1546 __ LoadObject(RAX, Bool::True()); | 1546 __ LoadObject(RAX, Bool::True()); |
1547 __ ret(); | 1547 __ ret(); |
1548 return true; | 1548 return true; |
1549 } | 1549 } |
1550 | 1550 |
1551 #undef __ | 1551 #undef __ |
1552 | 1552 |
1553 } // namespace dart | 1553 } // namespace dart |
1554 | 1554 |
1555 #endif // defined TARGET_ARCH_X64 | 1555 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |