| OLD | NEW |
| 1 // Copyright (c) 2013, 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" |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 RCX); | 90 RCX); |
| 91 | 91 |
| 92 // Set the length field in the growable array object to 0. | 92 // Set the length field in the growable array object to 0. |
| 93 __ ZeroInitSmiField(FieldAddress(RAX, GrowableObjectArray::length_offset())); | 93 __ ZeroInitSmiField(FieldAddress(RAX, GrowableObjectArray::length_offset())); |
| 94 __ ret(); // returns the newly allocated object in RAX. | 94 __ ret(); // returns the newly allocated object in RAX. |
| 95 | 95 |
| 96 __ Bind(&fall_through); | 96 __ Bind(&fall_through); |
| 97 } | 97 } |
| 98 | 98 |
| 99 | 99 |
| 100 // Access growable object array at specified index. | |
| 101 // On stack: growable array (+2), index (+1), return-address (+0). | |
| 102 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { | |
| 103 Label fall_through; | |
| 104 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. | |
| 105 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // GrowableArray. | |
| 106 __ testq(RCX, Immediate(kSmiTagMask)); | |
| 107 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | |
| 108 // Range check using _length field. | |
| 109 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); | |
| 110 // Runtime throws exception. | |
| 111 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | |
| 112 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. | |
| 113 | |
| 114 // Note that RCX is Smi, i.e, times 4. | |
| 115 ASSERT(kSmiTagShift == 1); | |
| 116 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset())); | |
| 117 __ ret(); | |
| 118 __ Bind(&fall_through); | |
| 119 } | |
| 120 | |
| 121 | |
| 122 // Set value into growable object array at specified index. | |
| 123 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). | |
| 124 void Intrinsifier::GrowableArraySetIndexed(Assembler* assembler) { | |
| 125 if (FLAG_enable_type_checks) { | |
| 126 return; | |
| 127 } | |
| 128 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. | |
| 129 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. | |
| 130 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // GrowableArray. | |
| 131 Label fall_through; | |
| 132 __ testq(RCX, Immediate(kSmiTagMask)); | |
| 133 __ j(NOT_ZERO, &fall_through); // Non-smi index. | |
| 134 // Range check using _length field. | |
| 135 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); | |
| 136 // Runtime throws exception. | |
| 137 __ j(ABOVE_EQUAL, &fall_through); | |
| 138 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. | |
| 139 // Note that RCX is Smi, i.e, times 4. | |
| 140 ASSERT(kSmiTagShift == 1); | |
| 141 __ StoreIntoObject(RAX, | |
| 142 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()), | |
| 143 RDX); | |
| 144 __ ret(); | |
| 145 __ Bind(&fall_through); | |
| 146 } | |
| 147 | |
| 148 | |
| 149 // Set length of growable object array. The length cannot | |
| 150 // be greater than the length of the data container. | |
| 151 // On stack: growable array (+2), length (+1), return-address (+0). | |
| 152 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) { | |
| 153 Label fall_through; | |
| 154 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array. | |
| 155 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Length value. | |
| 156 __ testq(RCX, Immediate(kSmiTagMask)); | |
| 157 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length. | |
| 158 FieldAddress length_field(RAX, GrowableObjectArray::length_offset()); | |
| 159 __ StoreIntoSmiField(length_field, RCX); | |
| 160 __ ret(); | |
| 161 __ Bind(&fall_through); | |
| 162 } | |
| 163 | |
| 164 | |
| 165 // Set data of growable object array. | |
| 166 // On stack: growable array (+2), data (+1), return-address (+0). | |
| 167 void Intrinsifier::GrowableArraySetData(Assembler* assembler) { | |
| 168 if (FLAG_enable_type_checks) { | |
| 169 return; | |
| 170 } | |
| 171 Label fall_through; | |
| 172 __ movq(RBX, Address(RSP, + 1 * kWordSize)); /// Data. | |
| 173 __ testq(RBX, Immediate(kSmiTagMask)); | |
| 174 __ j(ZERO, &fall_through); // Data is Smi. | |
| 175 __ CompareClassId(RBX, kArrayCid); | |
| 176 __ j(NOT_EQUAL, &fall_through); | |
| 177 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array. | |
| 178 __ StoreIntoObject(RAX, | |
| 179 FieldAddress(RAX, GrowableObjectArray::data_offset()), | |
| 180 RBX); | |
| 181 __ ret(); | |
| 182 __ Bind(&fall_through); | |
| 183 } | |
| 184 | |
| 185 | |
| 186 // Add an element to growable array if it doesn't need to grow, otherwise | 100 // Add an element to growable array if it doesn't need to grow, otherwise |
| 187 // call into regular code. | 101 // call into regular code. |
| 188 // On stack: growable array (+2), value (+1), return-address (+0). | 102 // On stack: growable array (+2), value (+1), return-address (+0). |
| 189 void Intrinsifier::GrowableArray_add(Assembler* assembler) { | 103 void Intrinsifier::GrowableArray_add(Assembler* assembler) { |
| 190 // In checked mode we need to check the incoming argument. | 104 // In checked mode we need to check the incoming argument. |
| 191 if (FLAG_enable_type_checks) return; | 105 if (FLAG_enable_type_checks) return; |
| 192 Label fall_through; | 106 Label fall_through; |
| 193 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. | 107 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. |
| 194 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); | 108 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); |
| 195 // RCX: length. | 109 // RCX: length. |
| (...skipping 1824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2020 // Set return value to Isolate::current_tag_. | 1934 // Set return value to Isolate::current_tag_. |
| 2021 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); | 1935 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); |
| 2022 __ ret(); | 1936 __ ret(); |
| 2023 } | 1937 } |
| 2024 | 1938 |
| 2025 #undef __ | 1939 #undef __ |
| 2026 | 1940 |
| 2027 } // namespace dart | 1941 } // namespace dart |
| 2028 | 1942 |
| 2029 #endif // defined TARGET_ARCH_X64 | 1943 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |