Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: runtime/vm/intrinsifier_x64.cc

Issue 468793004: VM: Improve performance of method recognizer and unify the it with the intrinsifier. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intrinsifier_mips.cc ('k') | runtime/vm/method_recognizer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/instructions.h" 12 #include "vm/instructions.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DECLARE_FLAG(bool, enable_type_checks); 18 DECLARE_FLAG(bool, enable_type_checks);
19 19
20 // When entering intrinsics code: 20 // When entering intrinsics code:
21 // RBX: IC Data 21 // RBX: IC Data
22 // R10: Arguments descriptor 22 // R10: Arguments descriptor
23 // TOS: Return address 23 // TOS: Return address
24 // The RBX, R10 registers can be destroyed only if there is no slow-path (i.e., 24 // The RBX, R10 registers can be destroyed only if there is no slow-path (i.e.,
25 // the methods returns true). 25 // the methods returns true).
26 26
27 #define __ assembler-> 27 #define __ assembler->
28 28
29 29
30 void Intrinsifier::Array_getLength(Assembler* assembler) { 30 void Intrinsifier::ObjectArrayLength(Assembler* assembler) {
31 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 31 __ movq(RAX, Address(RSP, + 1 * kWordSize));
32 __ movq(RAX, FieldAddress(RAX, Array::length_offset())); 32 __ movq(RAX, FieldAddress(RAX, Array::length_offset()));
33 __ ret(); 33 __ ret();
34 } 34 }
35 35
36 36
37 void Intrinsifier::ImmutableList_getLength(Assembler* assembler) { 37 void Intrinsifier::ImmutableArrayLength(Assembler* assembler) {
38 Array_getLength(assembler); 38 ObjectArrayLength(assembler);
39 } 39 }
40 40
41 41
42 void Intrinsifier::Array_getIndexed(Assembler* assembler) { 42 void Intrinsifier::ObjectArrayGetIndexed(Assembler* assembler) {
43 Label fall_through; 43 Label fall_through;
44 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. 44 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
45 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. 45 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
46 __ testq(RCX, Immediate(kSmiTagMask)); 46 __ testq(RCX, Immediate(kSmiTagMask));
47 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 47 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
48 // Range check. 48 // Range check.
49 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); 49 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset()));
50 // Runtime throws exception. 50 // Runtime throws exception.
51 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 51 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
52 // Note that RBX is Smi, i.e, times 2. 52 // Note that RBX is Smi, i.e, times 2.
53 ASSERT(kSmiTagShift == 1); 53 ASSERT(kSmiTagShift == 1);
54 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset())); 54 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()));
55 __ ret(); 55 __ ret();
56 __ Bind(&fall_through); 56 __ Bind(&fall_through);
57 } 57 }
58 58
59 59
60 void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) { 60 void Intrinsifier::ImmutableArrayGetIndexed(Assembler* assembler) {
61 Array_getIndexed(assembler); 61 ObjectArrayGetIndexed(assembler);
62 } 62 }
63 63
64 64
65 void Intrinsifier::Array_setIndexed(Assembler* assembler) { 65 void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
66 if (FLAG_enable_type_checks) { 66 if (FLAG_enable_type_checks) {
67 return; 67 return;
68 } 68 }
69 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. 69 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
70 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. 70 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index.
71 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array. 71 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array.
72 Label fall_through; 72 Label fall_through;
73 __ testq(RCX, Immediate(kSmiTagMask)); 73 __ testq(RCX, Immediate(kSmiTagMask));
74 __ j(NOT_ZERO, &fall_through); 74 __ j(NOT_ZERO, &fall_through);
75 // Range check. 75 // Range check.
76 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); 76 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset()));
77 // Runtime throws exception. 77 // Runtime throws exception.
78 __ j(ABOVE_EQUAL, &fall_through); 78 __ j(ABOVE_EQUAL, &fall_through);
79 // Note that RBX is Smi, i.e, times 2. 79 // Note that RBX is Smi, i.e, times 2.
80 ASSERT(kSmiTagShift == 1); 80 ASSERT(kSmiTagShift == 1);
81 // Destroy RCX (ic data) as we will not continue in the function. 81 // Destroy RCX (ic data) as we will not continue in the function.
82 __ StoreIntoObject(RAX, 82 __ StoreIntoObject(RAX,
83 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()), 83 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()),
84 RDX); 84 RDX);
85 // Caller is responsible of preserving the value if necessary. 85 // Caller is responsible of preserving the value if necessary.
86 __ ret(); 86 __ ret();
87 __ Bind(&fall_through); 87 __ Bind(&fall_through);
88 } 88 }
89 89
90 90
91 // Allocate a GrowableObjectArray using the backing array specified. 91 // Allocate a GrowableObjectArray using the backing array specified.
92 // On stack: type argument (+2), data (+1), return-address (+0). 92 // On stack: type argument (+2), data (+1), return-address (+0).
93 void Intrinsifier::GrowableList_Allocate(Assembler* assembler) { 93 void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
94 // This snippet of inlined code uses the following registers: 94 // This snippet of inlined code uses the following registers:
95 // RAX, RCX, R13 95 // RAX, RCX, R13
96 // and the newly allocated object is returned in RAX. 96 // and the newly allocated object is returned in RAX.
97 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 97 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
98 const intptr_t kArrayOffset = 1 * kWordSize; 98 const intptr_t kArrayOffset = 1 * kWordSize;
99 Label fall_through; 99 Label fall_through;
100 100
101 // Try allocating in new space. 101 // Try allocating in new space.
102 const Class& cls = Class::Handle( 102 const Class& cls = Class::Handle(
103 Isolate::Current()->object_store()->growable_object_array_class()); 103 Isolate::Current()->object_store()->growable_object_array_class());
(...skipping 19 matching lines...) Expand all
123 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), 123 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()),
124 Immediate(0)); 124 Immediate(0));
125 __ ret(); // returns the newly allocated object in RAX. 125 __ ret(); // returns the newly allocated object in RAX.
126 126
127 __ Bind(&fall_through); 127 __ Bind(&fall_through);
128 } 128 }
129 129
130 130
131 // Get length of growable object array. 131 // Get length of growable object array.
132 // On stack: growable array (+1), return-address (+0). 132 // On stack: growable array (+1), return-address (+0).
133 void Intrinsifier::GrowableList_getLength(Assembler* assembler) { 133 void Intrinsifier::GrowableArrayLength(Assembler* assembler) {
134 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 134 __ movq(RAX, Address(RSP, + 1 * kWordSize));
135 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset())); 135 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
136 __ ret(); 136 __ ret();
137 } 137 }
138 138
139 139
140 void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) { 140 void Intrinsifier::GrowableArrayCapacity(Assembler* assembler) {
141 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 141 __ movq(RAX, Address(RSP, + 1 * kWordSize));
142 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); 142 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset()));
143 __ movq(RAX, FieldAddress(RAX, Array::length_offset())); 143 __ movq(RAX, FieldAddress(RAX, Array::length_offset()));
144 __ ret(); 144 __ ret();
145 } 145 }
146 146
147 147
148 // Access growable object array at specified index. 148 // Access growable object array at specified index.
149 // On stack: growable array (+2), index (+1), return-address (+0). 149 // On stack: growable array (+2), index (+1), return-address (+0).
150 void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) { 150 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) {
151 Label fall_through; 151 Label fall_through;
152 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. 152 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
153 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // GrowableArray. 153 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // GrowableArray.
154 __ testq(RCX, Immediate(kSmiTagMask)); 154 __ testq(RCX, Immediate(kSmiTagMask));
155 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 155 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
156 // Range check using _length field. 156 // Range check using _length field.
157 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); 157 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
158 // Runtime throws exception. 158 // Runtime throws exception.
159 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 159 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
160 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. 160 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data.
161 161
162 // Note that RCX is Smi, i.e, times 4. 162 // Note that RCX is Smi, i.e, times 4.
163 ASSERT(kSmiTagShift == 1); 163 ASSERT(kSmiTagShift == 1);
164 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset())); 164 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()));
165 __ ret(); 165 __ ret();
166 __ Bind(&fall_through); 166 __ Bind(&fall_through);
167 } 167 }
168 168
169 169
170 // Set value into growable object array at specified index. 170 // Set value into growable object array at specified index.
171 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). 171 // On stack: growable array (+3), index (+2), value (+1), return-address (+0).
172 void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) { 172 void Intrinsifier::GrowableArraySetIndexed(Assembler* assembler) {
173 if (FLAG_enable_type_checks) { 173 if (FLAG_enable_type_checks) {
174 return; 174 return;
175 } 175 }
176 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. 176 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
177 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. 177 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index.
178 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // GrowableArray. 178 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // GrowableArray.
179 Label fall_through; 179 Label fall_through;
180 __ testq(RCX, Immediate(kSmiTagMask)); 180 __ testq(RCX, Immediate(kSmiTagMask));
181 __ j(NOT_ZERO, &fall_through); // Non-smi index. 181 __ j(NOT_ZERO, &fall_through); // Non-smi index.
182 // Range check using _length field. 182 // Range check using _length field.
183 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); 183 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
184 // Runtime throws exception. 184 // Runtime throws exception.
185 __ j(ABOVE_EQUAL, &fall_through); 185 __ j(ABOVE_EQUAL, &fall_through);
186 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. 186 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data.
187 // Note that RCX is Smi, i.e, times 4. 187 // Note that RCX is Smi, i.e, times 4.
188 ASSERT(kSmiTagShift == 1); 188 ASSERT(kSmiTagShift == 1);
189 __ StoreIntoObject(RAX, 189 __ StoreIntoObject(RAX,
190 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()), 190 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()),
191 RDX); 191 RDX);
192 __ ret(); 192 __ ret();
193 __ Bind(&fall_through); 193 __ Bind(&fall_through);
194 } 194 }
195 195
196 196
197 // Set length of growable object array. The length cannot 197 // Set length of growable object array. The length cannot
198 // be greater than the length of the data container. 198 // be greater than the length of the data container.
199 // On stack: growable array (+2), length (+1), return-address (+0). 199 // On stack: growable array (+2), length (+1), return-address (+0).
200 void Intrinsifier::GrowableList_setLength(Assembler* assembler) { 200 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) {
201 Label fall_through; 201 Label fall_through;
202 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array. 202 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array.
203 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Length value. 203 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Length value.
204 __ testq(RCX, Immediate(kSmiTagMask)); 204 __ testq(RCX, Immediate(kSmiTagMask));
205 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length. 205 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length.
206 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), RCX); 206 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), RCX);
207 __ ret(); 207 __ ret();
208 __ Bind(&fall_through); 208 __ Bind(&fall_through);
209 } 209 }
210 210
211 211
212 // Set data of growable object array. 212 // Set data of growable object array.
213 // On stack: growable array (+2), data (+1), return-address (+0). 213 // On stack: growable array (+2), data (+1), return-address (+0).
214 void Intrinsifier::GrowableList_setData(Assembler* assembler) { 214 void Intrinsifier::GrowableArraySetData(Assembler* assembler) {
215 if (FLAG_enable_type_checks) { 215 if (FLAG_enable_type_checks) {
216 return; 216 return;
217 } 217 }
218 Label fall_through; 218 Label fall_through;
219 __ movq(RBX, Address(RSP, + 1 * kWordSize)); /// Data. 219 __ movq(RBX, Address(RSP, + 1 * kWordSize)); /// Data.
220 __ testq(RBX, Immediate(kSmiTagMask)); 220 __ testq(RBX, Immediate(kSmiTagMask));
221 __ j(ZERO, &fall_through); // Data is Smi. 221 __ j(ZERO, &fall_through); // Data is Smi.
222 __ CompareClassId(RBX, kArrayCid); 222 __ CompareClassId(RBX, kArrayCid);
223 __ j(NOT_EQUAL, &fall_through); 223 __ j(NOT_EQUAL, &fall_through);
224 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array. 224 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array.
225 __ StoreIntoObject(RAX, 225 __ StoreIntoObject(RAX,
226 FieldAddress(RAX, GrowableObjectArray::data_offset()), 226 FieldAddress(RAX, GrowableObjectArray::data_offset()),
227 RBX); 227 RBX);
228 __ ret(); 228 __ ret();
229 __ Bind(&fall_through); 229 __ Bind(&fall_through);
230 } 230 }
231 231
232 232
233 // Add an element to growable array if it doesn't need to grow, otherwise 233 // Add an element to growable array if it doesn't need to grow, otherwise
234 // call into regular code. 234 // call into regular code.
235 // On stack: growable array (+2), value (+1), return-address (+0). 235 // On stack: growable array (+2), value (+1), return-address (+0).
236 void Intrinsifier::GrowableList_add(Assembler* assembler) { 236 void Intrinsifier::GrowableArray_add(Assembler* assembler) {
237 // In checked mode we need to check the incoming argument. 237 // In checked mode we need to check the incoming argument.
238 if (FLAG_enable_type_checks) return; 238 if (FLAG_enable_type_checks) return;
239 Label fall_through; 239 Label fall_through;
240 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. 240 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
241 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); 241 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
242 // RCX: length. 242 // RCX: length.
243 __ movq(RDX, FieldAddress(RAX, GrowableObjectArray::data_offset())); 243 __ movq(RDX, FieldAddress(RAX, GrowableObjectArray::data_offset()));
244 // RDX: data. 244 // RDX: data.
245 // Compare length with capacity. 245 // Compare length with capacity.
246 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset())); 246 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset()));
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 __ movq(Address(RDI, 0), RBX); \ 352 __ movq(Address(RDI, 0), RBX); \
353 __ addq(RDI, Immediate(kWordSize)); \ 353 __ addq(RDI, Immediate(kWordSize)); \
354 __ jmp(&init_loop, Assembler::kNearJump); \ 354 __ jmp(&init_loop, Assembler::kNearJump); \
355 __ Bind(&done); \ 355 __ Bind(&done); \
356 \ 356 \
357 __ ret(); \ 357 __ ret(); \
358 __ Bind(&fall_through); \ 358 __ Bind(&fall_through); \
359 359
360 360
361 // Gets the length of a TypedData. 361 // Gets the length of a TypedData.
362 void Intrinsifier::TypedData_getLength(Assembler* assembler) { 362 void Intrinsifier::TypedDataLength(Assembler* assembler) {
363 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 363 __ movq(RAX, Address(RSP, + 1 * kWordSize));
364 __ movq(RAX, FieldAddress(RAX, TypedData::length_offset())); 364 __ movq(RAX, FieldAddress(RAX, TypedData::length_offset()));
365 __ ret(); 365 __ ret();
366 } 366 }
367 367
368 368
369 void Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) { 369 void Intrinsifier::Uint8ArrayGetIndexed(Assembler* assembler) {
370 Label fall_through; 370 Label fall_through;
371 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. 371 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
372 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. 372 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
373 __ testq(RCX, Immediate(kSmiTagMask)); 373 __ testq(RCX, Immediate(kSmiTagMask));
374 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 374 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
375 // Range check. 375 // Range check.
376 __ cmpq(RCX, FieldAddress(RAX, TypedData::length_offset())); 376 __ cmpq(RCX, FieldAddress(RAX, TypedData::length_offset()));
377 // Runtime throws exception. 377 // Runtime throws exception.
378 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 378 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
379 379
380 __ SmiUntag(RCX); 380 __ SmiUntag(RCX);
381 __ movzxb(RAX, FieldAddress(RAX, RCX, TIMES_1, TypedData::data_offset())); 381 __ movzxb(RAX, FieldAddress(RAX, RCX, TIMES_1, TypedData::data_offset()));
382 __ SmiTag(RAX); 382 __ SmiTag(RAX);
383 __ ret(); 383 __ ret();
384 __ Bind(&fall_through); 384 __ Bind(&fall_through);
385 } 385 }
386 386
387 387
388 void Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) { 388 void Intrinsifier::ExternalUint8ArrayGetIndexed(Assembler* assembler) {
389 Label fall_through; 389 Label fall_through;
390 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. 390 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
391 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. 391 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
392 __ testq(RCX, Immediate(kSmiTagMask)); 392 __ testq(RCX, Immediate(kSmiTagMask));
393 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 393 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
394 // Range check. 394 // Range check.
395 __ cmpq(RCX, FieldAddress(RAX, TypedData::length_offset())); 395 __ cmpq(RCX, FieldAddress(RAX, TypedData::length_offset()));
396 // Runtime throws exception. 396 // Runtime throws exception.
397 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 397 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
398 398
399 __ movq(RAX, FieldAddress(RAX, ExternalTypedData::data_offset())); 399 __ movq(RAX, FieldAddress(RAX, ExternalTypedData::data_offset()));
400 __ SmiUntag(RCX); 400 __ SmiUntag(RCX);
401 __ movzxb(RAX, Address(RAX, RCX, TIMES_1, 0)); 401 __ movzxb(RAX, Address(RAX, RCX, TIMES_1, 0));
402 __ SmiTag(RAX); 402 __ SmiTag(RAX);
403 __ ret(); 403 __ ret();
404 __ Bind(&fall_through); 404 __ Bind(&fall_through);
405 } 405 }
406 406
407 407
408 void Intrinsifier::Float64Array_getIndexed(Assembler* assembler) { 408 void Intrinsifier::Float64ArrayGetIndexed(Assembler* assembler) {
409 Label fall_through; 409 Label fall_through;
410 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. 410 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
411 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. 411 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
412 __ testq(RCX, Immediate(kSmiTagMask)); 412 __ testq(RCX, Immediate(kSmiTagMask));
413 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 413 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
414 // Range check. 414 // Range check.
415 __ cmpq(RCX, FieldAddress(RAX, TypedData::length_offset())); 415 __ cmpq(RCX, FieldAddress(RAX, TypedData::length_offset()));
416 // Runtime throws exception. 416 // Runtime throws exception.
417 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 417 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
418 418
(...skipping 12 matching lines...) Expand all
431 &fall_through, 431 &fall_through,
432 Assembler::kNearJump, 432 Assembler::kNearJump,
433 RAX, // Result register. 433 RAX, // Result register.
434 kNoRegister); 434 kNoRegister);
435 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); 435 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
436 __ ret(); 436 __ ret();
437 __ Bind(&fall_through); 437 __ Bind(&fall_through);
438 } 438 }
439 439
440 440
441 void Intrinsifier::Float64Array_setIndexed(Assembler* assembler) { 441 void Intrinsifier::Float64ArraySetIndexed(Assembler* assembler) {
442 Label fall_through; 442 Label fall_through;
443 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. 443 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index.
444 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array. 444 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array.
445 __ testq(RCX, Immediate(kSmiTagMask)); 445 __ testq(RCX, Immediate(kSmiTagMask));
446 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 446 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
447 // Range check. 447 // Range check.
448 __ cmpq(RCX, FieldAddress(RAX, TypedData::length_offset())); 448 __ cmpq(RCX, FieldAddress(RAX, TypedData::length_offset()));
449 // Runtime throws exception. 449 // Runtime throws exception.
450 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 450 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
451 451
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 __ ret(); 1157 __ ret();
1158 __ Bind(&is_zero); 1158 __ Bind(&is_zero);
1159 // Check for negative zero (get the sign bit). 1159 // Check for negative zero (get the sign bit).
1160 __ movmskpd(RAX, XMM0); 1160 __ movmskpd(RAX, XMM0);
1161 __ testq(RAX, Immediate(1)); 1161 __ testq(RAX, Immediate(1));
1162 __ j(NOT_ZERO, &is_true, Assembler::kNearJump); 1162 __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
1163 __ jmp(&is_false, Assembler::kNearJump); 1163 __ jmp(&is_false, Assembler::kNearJump);
1164 } 1164 }
1165 1165
1166 1166
1167 void Intrinsifier::Double_toInt(Assembler* assembler) { 1167 void Intrinsifier::DoubleToInteger(Assembler* assembler) {
1168 __ movq(RAX, Address(RSP, +1 * kWordSize)); 1168 __ movq(RAX, Address(RSP, +1 * kWordSize));
1169 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); 1169 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
1170 __ cvttsd2siq(RAX, XMM0); 1170 __ cvttsd2siq(RAX, XMM0);
1171 // Overflow is signalled with minint. 1171 // Overflow is signalled with minint.
1172 Label fall_through; 1172 Label fall_through;
1173 // Check for overflow and that it fits into Smi. 1173 // Check for overflow and that it fits into Smi.
1174 __ movq(RCX, RAX); 1174 __ movq(RCX, RAX);
1175 __ shlq(RCX, Immediate(1)); 1175 __ shlq(RCX, Immediate(1));
1176 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); 1176 __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
1177 __ SmiTag(RAX); 1177 __ SmiTag(RAX);
1178 __ ret(); 1178 __ ret();
1179 __ Bind(&fall_through); 1179 __ Bind(&fall_through);
1180 } 1180 }
1181 1181
1182 1182
1183 void Intrinsifier::Math_sqrt(Assembler* assembler) { 1183 void Intrinsifier::MathSqrt(Assembler* assembler) {
1184 Label fall_through, is_smi, double_op; 1184 Label fall_through, is_smi, double_op;
1185 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); 1185 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
1186 // Argument is double and is in RAX. 1186 // Argument is double and is in RAX.
1187 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); 1187 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
1188 __ Bind(&double_op); 1188 __ Bind(&double_op);
1189 __ sqrtsd(XMM0, XMM1); 1189 __ sqrtsd(XMM0, XMM1);
1190 const Class& double_class = Class::Handle( 1190 const Class& double_class = Class::Handle(
1191 Isolate::Current()->object_store()->double_class()); 1191 Isolate::Current()->object_store()->double_class());
1192 __ TryAllocate(double_class, 1192 __ TryAllocate(double_class,
1193 &fall_through, 1193 &fall_through,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 __ imulq(RCX, RAX); 1234 __ imulq(RCX, RAX);
1235 __ movl(RDX, addr_1); 1235 __ movl(RDX, addr_1);
1236 __ addq(RDX, RCX); 1236 __ addq(RDX, RCX);
1237 __ movl(addr_0, RDX); 1237 __ movl(addr_0, RDX);
1238 __ shrq(RDX, Immediate(32)); 1238 __ shrq(RDX, Immediate(32));
1239 __ movl(addr_1, RDX); 1239 __ movl(addr_1, RDX);
1240 __ ret(); 1240 __ ret();
1241 } 1241 }
1242 1242
1243 // Identity comparison. 1243 // Identity comparison.
1244 void Intrinsifier::Object_equal(Assembler* assembler) { 1244 void Intrinsifier::ObjectEquals(Assembler* assembler) {
1245 Label is_true; 1245 Label is_true;
1246 const intptr_t kReceiverOffset = 2; 1246 const intptr_t kReceiverOffset = 2;
1247 const intptr_t kArgumentOffset = 1; 1247 const intptr_t kArgumentOffset = 1;
1248 1248
1249 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize)); 1249 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize));
1250 __ cmpq(RAX, Address(RSP, + kReceiverOffset * kWordSize)); 1250 __ cmpq(RAX, Address(RSP, + kReceiverOffset * kWordSize));
1251 __ j(EQUAL, &is_true, Assembler::kNearJump); 1251 __ j(EQUAL, &is_true, Assembler::kNearJump);
1252 __ LoadObject(RAX, Bool::False(), PP); 1252 __ LoadObject(RAX, Bool::False(), PP);
1253 __ ret(); 1253 __ ret();
1254 __ Bind(&is_true); 1254 __ Bind(&is_true);
1255 __ LoadObject(RAX, Bool::True(), PP); 1255 __ LoadObject(RAX, Bool::True(), PP);
1256 __ ret(); 1256 __ ret();
1257 } 1257 }
1258 1258
1259 1259
1260 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1260 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1261 Label fall_through; 1261 Label fall_through;
1262 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. 1262 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object.
1263 __ movq(RAX, FieldAddress(RAX, String::hash_offset())); 1263 __ movq(RAX, FieldAddress(RAX, String::hash_offset()));
1264 __ cmpq(RAX, Immediate(0)); 1264 __ cmpq(RAX, Immediate(0));
1265 __ j(EQUAL, &fall_through, Assembler::kNearJump); 1265 __ j(EQUAL, &fall_through, Assembler::kNearJump);
1266 __ ret(); 1266 __ ret();
1267 __ Bind(&fall_through); 1267 __ Bind(&fall_through);
1268 // Hash not yet computed. 1268 // Hash not yet computed.
1269 } 1269 }
1270 1270
1271 1271
1272 void Intrinsifier::String_getLength(Assembler* assembler) { 1272 void Intrinsifier::StringBaseLength(Assembler* assembler) {
1273 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. 1273 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object.
1274 __ movq(RAX, FieldAddress(RAX, String::length_offset())); 1274 __ movq(RAX, FieldAddress(RAX, String::length_offset()));
1275 __ ret(); 1275 __ ret();
1276 } 1276 }
1277 1277
1278 1278
1279 void Intrinsifier::String_codeUnitAt(Assembler* assembler) { 1279 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
1280 Label fall_through, try_two_byte_string; 1280 Label fall_through, try_two_byte_string;
1281 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. 1281 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
1282 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // String. 1282 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // String.
1283 __ testq(RCX, Immediate(kSmiTagMask)); 1283 __ testq(RCX, Immediate(kSmiTagMask));
1284 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 1284 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
1285 // Range check. 1285 // Range check.
1286 __ cmpq(RCX, FieldAddress(RAX, String::length_offset())); 1286 __ cmpq(RCX, FieldAddress(RAX, String::length_offset()));
1287 // Runtime throws exception. 1287 // Runtime throws exception.
1288 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 1288 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
1289 __ CompareClassId(RAX, kOneByteStringCid); 1289 __ CompareClassId(RAX, kOneByteStringCid);
1290 __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump); 1290 __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
1291 __ SmiUntag(RCX); 1291 __ SmiUntag(RCX);
1292 __ movzxb(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset())); 1292 __ movzxb(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
1293 __ SmiTag(RAX); 1293 __ SmiTag(RAX);
1294 __ ret(); 1294 __ ret();
1295 1295
1296 __ Bind(&try_two_byte_string); 1296 __ Bind(&try_two_byte_string);
1297 __ CompareClassId(RAX, kTwoByteStringCid); 1297 __ CompareClassId(RAX, kTwoByteStringCid);
1298 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1298 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1299 ASSERT(kSmiTagShift == 1); 1299 ASSERT(kSmiTagShift == 1);
1300 __ movzxw(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset())); 1300 __ movzxw(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
1301 __ SmiTag(RAX); 1301 __ SmiTag(RAX);
1302 __ ret(); 1302 __ ret();
1303 1303
1304 __ Bind(&fall_through); 1304 __ Bind(&fall_through);
1305 } 1305 }
1306 1306
1307 1307
1308 void Intrinsifier::String_getIsEmpty(Assembler* assembler) { 1308 void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
1309 Label is_true; 1309 Label is_true;
1310 // Get length. 1310 // Get length.
1311 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. 1311 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object.
1312 __ movq(RAX, FieldAddress(RAX, String::length_offset())); 1312 __ movq(RAX, FieldAddress(RAX, String::length_offset()));
1313 __ cmpq(RAX, Immediate(Smi::RawValue(0))); 1313 __ cmpq(RAX, Immediate(Smi::RawValue(0)));
1314 __ j(EQUAL, &is_true, Assembler::kNearJump); 1314 __ j(EQUAL, &is_true, Assembler::kNearJump);
1315 __ LoadObject(RAX, Bool::False(), PP); 1315 __ LoadObject(RAX, Bool::False(), PP);
1316 __ ret(); 1316 __ ret();
1317 __ Bind(&is_true); 1317 __ Bind(&is_true);
1318 __ LoadObject(RAX, Bool::True(), PP); 1318 __ LoadObject(RAX, Bool::True(), PP);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 __ movb(FieldAddress(RAX, RDX, TIMES_1, OneByteString::data_offset()), RBX); 1510 __ movb(FieldAddress(RAX, RDX, TIMES_1, OneByteString::data_offset()), RBX);
1511 __ incq(RDX); 1511 __ incq(RDX);
1512 __ Bind(&check); 1512 __ Bind(&check);
1513 __ cmpq(RDX, RCX); 1513 __ cmpq(RDX, RCX);
1514 __ j(LESS, &loop, Assembler::kNearJump); 1514 __ j(LESS, &loop, Assembler::kNearJump);
1515 __ ret(); 1515 __ ret();
1516 __ Bind(&fall_through); 1516 __ Bind(&fall_through);
1517 } 1517 }
1518 1518
1519 1519
1520 void Intrinsifier::OneByteString_setAt(Assembler* assembler) { 1520 void Intrinsifier::OneByteStringSetAt(Assembler* assembler) {
1521 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Value. 1521 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Value.
1522 __ movq(RBX, Address(RSP, + 2 * kWordSize)); // Index. 1522 __ movq(RBX, Address(RSP, + 2 * kWordSize)); // Index.
1523 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // OneByteString. 1523 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // OneByteString.
1524 __ SmiUntag(RBX); 1524 __ SmiUntag(RBX);
1525 __ SmiUntag(RCX); 1525 __ SmiUntag(RCX);
1526 __ movb(FieldAddress(RAX, RBX, TIMES_1, OneByteString::data_offset()), RCX); 1526 __ movb(FieldAddress(RAX, RBX, TIMES_1, OneByteString::data_offset()), RCX);
1527 __ ret(); 1527 __ ret();
1528 } 1528 }
1529 1529
1530 1530
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 // Set return value to Isolate::current_tag_. 1651 // Set return value to Isolate::current_tag_.
1652 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); 1652 __ movq(RAX, Address(RBX, Isolate::current_tag_offset()));
1653 __ ret(); 1653 __ ret();
1654 } 1654 }
1655 1655
1656 #undef __ 1656 #undef __
1657 1657
1658 } // namespace dart 1658 } // namespace dart
1659 1659
1660 #endif // defined TARGET_ARCH_X64 1660 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_mips.cc ('k') | runtime/vm/method_recognizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698