| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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" |
| 11 #include "vm/assembler_macros.h" | 11 #include "vm/assembler_macros.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 38 // Compute the size to be allocated, it is based on the array length | 38 // Compute the size to be allocated, it is based on the array length |
| 39 // and is computed as: | 39 // and is computed as: |
| 40 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). | 40 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). |
| 41 __ movq(RDI, Address(RSP, kArrayLengthOffset)); // Array Length. | 41 __ movq(RDI, Address(RSP, kArrayLengthOffset)); // Array Length. |
| 42 // Assert that length is a Smi. | 42 // Assert that length is a Smi. |
| 43 __ testq(RDI, Immediate(kSmiTagSize)); | 43 __ testq(RDI, Immediate(kSmiTagSize)); |
| 44 __ j(NOT_ZERO, &fall_through); | 44 __ j(NOT_ZERO, &fall_through); |
| 45 __ cmpq(RDI, Immediate(0)); | 45 __ cmpq(RDI, Immediate(0)); |
| 46 __ j(LESS, &fall_through); | 46 __ j(LESS, &fall_through); |
| 47 // Check for maximum allowed length. | 47 // Check for maximum allowed length. |
| 48 const Immediate max_len = | 48 const Immediate& max_len = |
| 49 Immediate(reinterpret_cast<int64_t>(Smi::New(Array::kMaxElements))); | 49 Immediate(reinterpret_cast<int64_t>(Smi::New(Array::kMaxElements))); |
| 50 __ cmpq(RDI, max_len); | 50 __ cmpq(RDI, max_len); |
| 51 __ j(GREATER, &fall_through); | 51 __ j(GREATER, &fall_through); |
| 52 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 52 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
| 53 __ leaq(RDI, Address(RDI, TIMES_4, fixed_size)); // RDI is a Smi. | 53 __ leaq(RDI, Address(RDI, TIMES_4, fixed_size)); // RDI is a Smi. |
| 54 ASSERT(kSmiTagShift == 1); | 54 ASSERT(kSmiTagShift == 1); |
| 55 __ andq(RDI, Immediate(-kObjectAlignment)); | 55 __ andq(RDI, Immediate(-kObjectAlignment)); |
| 56 | 56 |
| 57 Isolate* isolate = Isolate::Current(); | 57 Isolate* isolate = Isolate::Current(); |
| 58 Heap* heap = isolate->heap(); | 58 Heap* heap = isolate->heap(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 __ movq(RDI, Address(RSP, kArrayLengthOffset)); // Array Length. | 110 __ movq(RDI, Address(RSP, kArrayLengthOffset)); // Array Length. |
| 111 __ StoreIntoObjectNoBarrier(RAX, | 111 __ StoreIntoObjectNoBarrier(RAX, |
| 112 FieldAddress(RAX, Array::length_offset()), | 112 FieldAddress(RAX, Array::length_offset()), |
| 113 RDI); | 113 RDI); |
| 114 | 114 |
| 115 // Initialize all array elements to raw_null. | 115 // Initialize all array elements to raw_null. |
| 116 // RAX: new object start as a tagged pointer. | 116 // RAX: new object start as a tagged pointer. |
| 117 // RCX: new object end address. | 117 // RCX: new object end address. |
| 118 // RDI: iterator which initially points to the start of the variable | 118 // RDI: iterator which initially points to the start of the variable |
| 119 // data area to be initialized. | 119 // data area to be initialized. |
| 120 const Immediate raw_null = | 120 const Immediate& raw_null = |
| 121 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 121 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 122 __ leaq(RDI, FieldAddress(RAX, sizeof(RawArray))); | 122 __ leaq(RDI, FieldAddress(RAX, sizeof(RawArray))); |
| 123 Label done; | 123 Label done; |
| 124 Label init_loop; | 124 Label init_loop; |
| 125 __ Bind(&init_loop); | 125 __ Bind(&init_loop); |
| 126 __ cmpq(RDI, RCX); | 126 __ cmpq(RDI, RCX); |
| 127 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); | 127 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); |
| 128 __ movq(Address(RDI, 0), raw_null); | 128 __ movq(Address(RDI, 0), raw_null); |
| 129 __ addq(RDI, Immediate(kWordSize)); | 129 __ addq(RDI, Immediate(kWordSize)); |
| 130 __ jmp(&init_loop, Assembler::kNearJump); | 130 __ jmp(&init_loop, Assembler::kNearJump); |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 if (FLAG_enable_type_checks) return false; | 387 if (FLAG_enable_type_checks) return false; |
| 388 Label fall_through; | 388 Label fall_through; |
| 389 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. | 389 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. |
| 390 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); | 390 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); |
| 391 // RCX: length. | 391 // RCX: length. |
| 392 __ movq(RDX, FieldAddress(RAX, GrowableObjectArray::data_offset())); | 392 __ movq(RDX, FieldAddress(RAX, GrowableObjectArray::data_offset())); |
| 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 = |
| 398 Immediate(reinterpret_cast<int64_t>(Smi::New(1))); |
| 398 // len = len + 1; | 399 // len = len + 1; |
| 399 __ addq(FieldAddress(RAX, GrowableObjectArray::length_offset()), value_one); | 400 __ addq(FieldAddress(RAX, GrowableObjectArray::length_offset()), value_one); |
| 400 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Value | 401 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Value |
| 401 ASSERT(kSmiTagShift == 1); | 402 ASSERT(kSmiTagShift == 1); |
| 402 __ StoreIntoObject(RDX, | 403 __ StoreIntoObject(RDX, |
| 403 FieldAddress(RDX, RCX, TIMES_4, Array::data_offset()), | 404 FieldAddress(RDX, RCX, TIMES_4, Array::data_offset()), |
| 404 RAX); | 405 RAX); |
| 405 const Immediate raw_null = | 406 const Immediate& raw_null = |
| 406 Immediate(reinterpret_cast<int64_t>(Object::null())); | 407 Immediate(reinterpret_cast<int64_t>(Object::null())); |
| 407 __ movq(RAX, raw_null); | 408 __ movq(RAX, raw_null); |
| 408 __ ret(); | 409 __ ret(); |
| 409 __ Bind(&fall_through); | 410 __ Bind(&fall_through); |
| 410 return false; | 411 return false; |
| 411 } | 412 } |
| 412 | 413 |
| 413 | 414 |
| 414 bool Intrinsifier::ByteArrayBase_getLength(Assembler* assembler) { | 415 bool Intrinsifier::ByteArrayBase_getLength(Assembler* assembler) { |
| 415 __ movq(RAX, Address(RSP, + 1 * kWordSize)); | 416 __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1126 | 1127 |
| 1127 | 1128 |
| 1128 bool Intrinsifier::Integer_equal(Assembler* assembler) { | 1129 bool Intrinsifier::Integer_equal(Assembler* assembler) { |
| 1129 return Integer_equalToInteger(assembler); | 1130 return Integer_equalToInteger(assembler); |
| 1130 } | 1131 } |
| 1131 | 1132 |
| 1132 | 1133 |
| 1133 bool Intrinsifier::Integer_sar(Assembler* assembler) { | 1134 bool Intrinsifier::Integer_sar(Assembler* assembler) { |
| 1134 Label fall_through, shift_count_ok; | 1135 Label fall_through, shift_count_ok; |
| 1135 TestBothArgumentsSmis(assembler, &fall_through); | 1136 TestBothArgumentsSmis(assembler, &fall_through); |
| 1136 Immediate count_limit = Immediate(0x3F); | 1137 const Immediate& count_limit = Immediate(0x3F); |
| 1137 // Check that the count is not larger than what the hardware can handle. | 1138 // Check that the count is not larger than what the hardware can handle. |
| 1138 // For shifting right a Smi the result is the same for all numbers | 1139 // For shifting right a Smi the result is the same for all numbers |
| 1139 // >= count_limit. | 1140 // >= count_limit. |
| 1140 __ SmiUntag(RAX); | 1141 __ SmiUntag(RAX); |
| 1141 // Negative counts throw exception. | 1142 // Negative counts throw exception. |
| 1142 __ cmpq(RAX, Immediate(0)); | 1143 __ cmpq(RAX, Immediate(0)); |
| 1143 __ j(LESS, &fall_through, Assembler::kNearJump); | 1144 __ j(LESS, &fall_through, Assembler::kNearJump); |
| 1144 __ cmpq(RAX, count_limit); | 1145 __ cmpq(RAX, count_limit); |
| 1145 __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump); | 1146 __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump); |
| 1146 __ movq(RAX, count_limit); | 1147 __ movq(RAX, count_limit); |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 __ LoadObject(RAX, Bool::True()); | 1547 __ LoadObject(RAX, Bool::True()); |
| 1547 __ ret(); | 1548 __ ret(); |
| 1548 return true; | 1549 return true; |
| 1549 } | 1550 } |
| 1550 | 1551 |
| 1551 #undef __ | 1552 #undef __ |
| 1552 | 1553 |
| 1553 } // namespace dart | 1554 } // namespace dart |
| 1554 | 1555 |
| 1555 #endif // defined TARGET_ARCH_X64 | 1556 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |