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 |