| 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 |