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

Side by Side Diff: runtime/vm/intrinsifier_ia32.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_arm64.cc ('k') | runtime/vm/intrinsifier_mips.cc » ('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 // The intrinsic code below is executed before a method has built its frame. 5 // The intrinsic code below is executed before a method has built its frame.
6 // The return address is on the stack and the arguments below it. 6 // The return address is on the stack and the arguments below it.
7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved.
8 // Each intrinsification method returns true if the corresponding 8 // Each intrinsification method returns true if the corresponding
9 // Dart method was intrinsified. 9 // Dart method was intrinsified.
10 10
(...skipping 11 matching lines...) Expand all
22 #include "vm/symbols.h" 22 #include "vm/symbols.h"
23 23
24 namespace dart { 24 namespace dart {
25 25
26 DECLARE_FLAG(bool, enable_type_checks); 26 DECLARE_FLAG(bool, enable_type_checks);
27 27
28 28
29 #define __ assembler-> 29 #define __ assembler->
30 30
31 31
32 void Intrinsifier::Array_getLength(Assembler* assembler) { 32 void Intrinsifier::ObjectArrayLength(Assembler* assembler) {
33 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 33 __ movl(EAX, Address(ESP, + 1 * kWordSize));
34 __ movl(EAX, FieldAddress(EAX, Array::length_offset())); 34 __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
35 __ ret(); 35 __ ret();
36 } 36 }
37 37
38 38
39 void Intrinsifier::ImmutableList_getLength(Assembler* assembler) { 39 void Intrinsifier::ImmutableArrayLength(Assembler* assembler) {
40 Array_getLength(assembler); 40 ObjectArrayLength(assembler);
41 } 41 }
42 42
43 43
44 void Intrinsifier::Array_getIndexed(Assembler* assembler) { 44 void Intrinsifier::ObjectArrayGetIndexed(Assembler* assembler) {
45 Label fall_through; 45 Label fall_through;
46 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 46 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
47 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. 47 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
48 __ testl(EBX, Immediate(kSmiTagMask)); 48 __ testl(EBX, Immediate(kSmiTagMask));
49 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 49 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
50 // Range check. 50 // Range check.
51 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); 51 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset()));
52 // Runtime throws exception. 52 // Runtime throws exception.
53 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 53 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
54 // Note that EBX is Smi, i.e, times 2. 54 // Note that EBX is Smi, i.e, times 2.
55 ASSERT(kSmiTagShift == 1); 55 ASSERT(kSmiTagShift == 1);
56 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset())); 56 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()));
57 __ ret(); 57 __ ret();
58 __ Bind(&fall_through); 58 __ Bind(&fall_through);
59 } 59 }
60 60
61 61
62 void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) { 62 void Intrinsifier::ImmutableArrayGetIndexed(Assembler* assembler) {
63 Array_getIndexed(assembler); 63 ObjectArrayGetIndexed(assembler);
64 } 64 }
65 65
66 66
67 static intptr_t ComputeObjectArrayTypeArgumentsOffset() { 67 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
68 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 68 const Library& core_lib = Library::Handle(Library::CoreLibrary());
69 const Class& cls = Class::Handle( 69 const Class& cls = Class::Handle(
70 core_lib.LookupClassAllowPrivate(Symbols::_List())); 70 core_lib.LookupClassAllowPrivate(Symbols::_List()));
71 ASSERT(!cls.IsNull()); 71 ASSERT(!cls.IsNull());
72 ASSERT(cls.NumTypeArguments() == 1); 72 ASSERT(cls.NumTypeArguments() == 1);
73 const intptr_t field_offset = cls.type_arguments_field_offset(); 73 const intptr_t field_offset = cls.type_arguments_field_offset();
74 ASSERT(field_offset != Class::kNoTypeArguments); 74 ASSERT(field_offset != Class::kNoTypeArguments);
75 return field_offset; 75 return field_offset;
76 } 76 }
77 77
78 78
79 // Intrinsify only for Smi value and index. Non-smi values need a store buffer 79 // Intrinsify only for Smi value and index. Non-smi values need a store buffer
80 // update. Array length is always a Smi. 80 // update. Array length is always a Smi.
81 void Intrinsifier::Array_setIndexed(Assembler* assembler) { 81 void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
82 Label fall_through; 82 Label fall_through;
83 if (FLAG_enable_type_checks) { 83 if (FLAG_enable_type_checks) {
84 const intptr_t type_args_field_offset = 84 const intptr_t type_args_field_offset =
85 ComputeObjectArrayTypeArgumentsOffset(); 85 ComputeObjectArrayTypeArgumentsOffset();
86 // Inline simple tests (Smi, null), fallthrough if not positive. 86 // Inline simple tests (Smi, null), fallthrough if not positive.
87 const Immediate& raw_null = 87 const Immediate& raw_null =
88 Immediate(reinterpret_cast<intptr_t>(Object::null())); 88 Immediate(reinterpret_cast<intptr_t>(Object::null()));
89 Label checked_ok; 89 Label checked_ok;
90 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. 90 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value.
91 // Null value is valid for any type. 91 // Null value is valid for any type.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), 128 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()),
129 ECX); 129 ECX);
130 // Caller is responsible of preserving the value if necessary. 130 // Caller is responsible of preserving the value if necessary.
131 __ ret(); 131 __ ret();
132 __ Bind(&fall_through); 132 __ Bind(&fall_through);
133 } 133 }
134 134
135 135
136 // Allocate a GrowableObjectArray using the backing array specified. 136 // Allocate a GrowableObjectArray using the backing array specified.
137 // On stack: type argument (+2), data (+1), return-address (+0). 137 // On stack: type argument (+2), data (+1), return-address (+0).
138 void Intrinsifier::GrowableList_Allocate(Assembler* assembler) { 138 void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
139 // This snippet of inlined code uses the following registers: 139 // This snippet of inlined code uses the following registers:
140 // EAX, EBX 140 // EAX, EBX
141 // and the newly allocated object is returned in EAX. 141 // and the newly allocated object is returned in EAX.
142 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 142 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
143 const intptr_t kArrayOffset = 1 * kWordSize; 143 const intptr_t kArrayOffset = 1 * kWordSize;
144 Label fall_through; 144 Label fall_through;
145 145
146 // Try allocating in new space. 146 // Try allocating in new space.
147 const Class& cls = Class::Handle( 147 const Class& cls = Class::Handle(
148 Isolate::Current()->object_store()->growable_object_array_class()); 148 Isolate::Current()->object_store()->growable_object_array_class());
(...skipping 19 matching lines...) Expand all
168 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), 168 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()),
169 Immediate(0)); 169 Immediate(0));
170 __ ret(); // returns the newly allocated object in EAX. 170 __ ret(); // returns the newly allocated object in EAX.
171 171
172 __ Bind(&fall_through); 172 __ Bind(&fall_through);
173 } 173 }
174 174
175 175
176 // Get length of growable object array. 176 // Get length of growable object array.
177 // On stack: growable array (+1), return-address (+0). 177 // On stack: growable array (+1), return-address (+0).
178 void Intrinsifier::GrowableList_getLength(Assembler* assembler) { 178 void Intrinsifier::GrowableArrayLength(Assembler* assembler) {
179 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 179 __ movl(EAX, Address(ESP, + 1 * kWordSize));
180 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 180 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
181 __ ret(); 181 __ ret();
182 } 182 }
183 183
184 184
185 // Get capacity of growable object array. 185 // Get capacity of growable object array.
186 // On stack: growable array (+1), return-address (+0). 186 // On stack: growable array (+1), return-address (+0).
187 void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) { 187 void Intrinsifier::GrowableArrayCapacity(Assembler* assembler) {
188 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 188 __ movl(EAX, Address(ESP, + 1 * kWordSize));
189 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); 189 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset()));
190 __ movl(EAX, FieldAddress(EAX, Array::length_offset())); 190 __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
191 __ ret(); 191 __ ret();
192 } 192 }
193 193
194 194
195 // Access growable object array at specified index. 195 // Access growable object array at specified index.
196 // On stack: growable array (+2), index (+1), return-address (+0). 196 // On stack: growable array (+2), index (+1), return-address (+0).
197 void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) { 197 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) {
198 Label fall_through; 198 Label fall_through;
199 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 199 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
200 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray. 200 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray.
201 __ testl(EBX, Immediate(kSmiTagMask)); 201 __ testl(EBX, Immediate(kSmiTagMask));
202 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 202 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
203 // Range check using _length field. 203 // Range check using _length field.
204 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 204 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
205 // Runtime throws exception. 205 // Runtime throws exception.
206 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 206 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
207 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. 207 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data.
208 208
209 // Note that EBX is Smi, i.e, times 2. 209 // Note that EBX is Smi, i.e, times 2.
210 ASSERT(kSmiTagShift == 1); 210 ASSERT(kSmiTagShift == 1);
211 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset())); 211 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()));
212 __ ret(); 212 __ ret();
213 __ Bind(&fall_through); 213 __ Bind(&fall_through);
214 } 214 }
215 215
216 216
217 // Set value into growable object array at specified index. 217 // Set value into growable object array at specified index.
218 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). 218 // On stack: growable array (+3), index (+2), value (+1), return-address (+0).
219 void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) { 219 void Intrinsifier::GrowableArraySetIndexed(Assembler* assembler) {
220 if (FLAG_enable_type_checks) { 220 if (FLAG_enable_type_checks) {
221 return; 221 return;
222 } 222 }
223 Label fall_through; 223 Label fall_through;
224 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. 224 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index.
225 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. 225 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray.
226 __ testl(EBX, Immediate(kSmiTagMask)); 226 __ testl(EBX, Immediate(kSmiTagMask));
227 __ j(NOT_ZERO, &fall_through); // Non-smi index. 227 __ j(NOT_ZERO, &fall_through); // Non-smi index.
228 // Range check using _length field. 228 // Range check using _length field.
229 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 229 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
230 // Runtime throws exception. 230 // Runtime throws exception.
231 __ j(ABOVE_EQUAL, &fall_through); 231 __ j(ABOVE_EQUAL, &fall_through);
232 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. 232 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data.
233 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. 233 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value.
234 // Note that EBX is Smi, i.e, times 2. 234 // Note that EBX is Smi, i.e, times 2.
235 ASSERT(kSmiTagShift == 1); 235 ASSERT(kSmiTagShift == 1);
236 __ StoreIntoObject(EAX, 236 __ StoreIntoObject(EAX,
237 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), 237 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()),
238 EDI); 238 EDI);
239 __ ret(); 239 __ ret();
240 __ Bind(&fall_through); 240 __ Bind(&fall_through);
241 } 241 }
242 242
243 243
244 // Set length of growable object array. The length cannot 244 // Set length of growable object array. The length cannot
245 // be greater than the length of the data container. 245 // be greater than the length of the data container.
246 // On stack: growable array (+2), length (+1), return-address (+0). 246 // On stack: growable array (+2), length (+1), return-address (+0).
247 void Intrinsifier::GrowableList_setLength(Assembler* assembler) { 247 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) {
248 Label fall_through; 248 Label fall_through;
249 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array. 249 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array.
250 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Length value. 250 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Length value.
251 __ testl(EBX, Immediate(kSmiTagMask)); 251 __ testl(EBX, Immediate(kSmiTagMask));
252 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length. 252 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length.
253 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), EBX); 253 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), EBX);
254 __ ret(); 254 __ ret();
255 __ Bind(&fall_through); 255 __ Bind(&fall_through);
256 } 256 }
257 257
258 258
259 // Set data of growable object array. 259 // Set data of growable object array.
260 // On stack: growable array (+2), data (+1), return-address (+0). 260 // On stack: growable array (+2), data (+1), return-address (+0).
261 void Intrinsifier::GrowableList_setData(Assembler* assembler) { 261 void Intrinsifier::GrowableArraySetData(Assembler* assembler) {
262 if (FLAG_enable_type_checks) { 262 if (FLAG_enable_type_checks) {
263 return; 263 return;
264 } 264 }
265 Label fall_through; 265 Label fall_through;
266 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Data. 266 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Data.
267 // Check that data is an ObjectArray. 267 // Check that data is an ObjectArray.
268 __ testl(EBX, Immediate(kSmiTagMask)); 268 __ testl(EBX, Immediate(kSmiTagMask));
269 __ j(ZERO, &fall_through); // Data is Smi. 269 __ j(ZERO, &fall_through); // Data is Smi.
270 __ CompareClassId(EBX, kArrayCid, EAX); 270 __ CompareClassId(EBX, kArrayCid, EAX);
271 __ j(NOT_EQUAL, &fall_through); 271 __ j(NOT_EQUAL, &fall_through);
272 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array. 272 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array.
273 __ StoreIntoObject(EAX, 273 __ StoreIntoObject(EAX,
274 FieldAddress(EAX, GrowableObjectArray::data_offset()), 274 FieldAddress(EAX, GrowableObjectArray::data_offset()),
275 EBX); 275 EBX);
276 __ ret(); 276 __ ret();
277 __ Bind(&fall_through); 277 __ Bind(&fall_through);
278 } 278 }
279 279
280 280
281 // Add an element to growable array if it doesn't need to grow, otherwise 281 // Add an element to growable array if it doesn't need to grow, otherwise
282 // call into regular code. 282 // call into regular code.
283 // On stack: growable array (+2), value (+1), return-address (+0). 283 // On stack: growable array (+2), value (+1), return-address (+0).
284 void Intrinsifier::GrowableList_add(Assembler* assembler) { 284 void Intrinsifier::GrowableArray_add(Assembler* assembler) {
285 // In checked mode we need to type-check the incoming argument. 285 // In checked mode we need to type-check the incoming argument.
286 if (FLAG_enable_type_checks) return; 286 if (FLAG_enable_type_checks) return;
287 287
288 Label fall_through; 288 Label fall_through;
289 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. 289 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
290 __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 290 __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
291 // EBX: length. 291 // EBX: length.
292 __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset())); 292 __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset()));
293 // EDI: data. 293 // EDI: data.
294 // Compare length with capacity. 294 // Compare length with capacity.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 __ addl(EDI, Immediate(kWordSize)); \ 400 __ addl(EDI, Immediate(kWordSize)); \
401 __ jmp(&init_loop, Assembler::kNearJump); \ 401 __ jmp(&init_loop, Assembler::kNearJump); \
402 __ Bind(&done); \ 402 __ Bind(&done); \
403 \ 403 \
404 __ ret(); \ 404 __ ret(); \
405 __ Bind(&fall_through); \ 405 __ Bind(&fall_through); \
406 406
407 407
408 408
409 // Gets the length of a TypedData. 409 // Gets the length of a TypedData.
410 void Intrinsifier::TypedData_getLength(Assembler* assembler) { 410 void Intrinsifier::TypedDataLength(Assembler* assembler) {
411 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 411 __ movl(EAX, Address(ESP, + 1 * kWordSize));
412 __ movl(EAX, FieldAddress(EAX, TypedData::length_offset())); 412 __ movl(EAX, FieldAddress(EAX, TypedData::length_offset()));
413 __ ret(); 413 __ ret();
414 } 414 }
415 415
416 416
417 void Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) { 417 void Intrinsifier::Uint8ArrayGetIndexed(Assembler* assembler) {
418 Label fall_through; 418 Label fall_through;
419 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 419 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
420 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. 420 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
421 __ testl(EBX, Immediate(kSmiTagMask)); 421 __ testl(EBX, Immediate(kSmiTagMask));
422 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 422 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
423 // Range check. 423 // Range check.
424 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset())); 424 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset()));
425 // Runtime throws exception. 425 // Runtime throws exception.
426 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 426 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
427 427
428 __ SmiUntag(EBX); 428 __ SmiUntag(EBX);
429 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, TypedData::data_offset())); 429 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, TypedData::data_offset()));
430 __ SmiTag(EAX); 430 __ SmiTag(EAX);
431 __ ret(); 431 __ ret();
432 __ Bind(&fall_through); 432 __ Bind(&fall_through);
433 } 433 }
434 434
435 435
436 void Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) { 436 void Intrinsifier::ExternalUint8ArrayGetIndexed(Assembler* assembler) {
437 Label fall_through; 437 Label fall_through;
438 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 438 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
439 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. 439 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
440 __ testl(EBX, Immediate(kSmiTagMask)); 440 __ testl(EBX, Immediate(kSmiTagMask));
441 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 441 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
442 // Range check. 442 // Range check.
443 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset())); 443 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset()));
444 // Runtime throws exception. 444 // Runtime throws exception.
445 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 445 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
446 446
447 __ movl(EAX, FieldAddress(EAX, ExternalTypedData::data_offset())); 447 __ movl(EAX, FieldAddress(EAX, ExternalTypedData::data_offset()));
448 __ SmiUntag(EBX); 448 __ SmiUntag(EBX);
449 __ movzxb(EAX, Address(EAX, EBX, TIMES_1, 0)); 449 __ movzxb(EAX, Address(EAX, EBX, TIMES_1, 0));
450 __ SmiTag(EAX); 450 __ SmiTag(EAX);
451 __ ret(); 451 __ ret();
452 __ Bind(&fall_through); 452 __ Bind(&fall_through);
453 } 453 }
454 454
455 455
456 void Intrinsifier::Float64Array_getIndexed(Assembler* assembler) { 456 void Intrinsifier::Float64ArrayGetIndexed(Assembler* assembler) {
457 Label fall_through; 457 Label fall_through;
458 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 458 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
459 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. 459 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
460 __ testl(EBX, Immediate(kSmiTagMask)); 460 __ testl(EBX, Immediate(kSmiTagMask));
461 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 461 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
462 // Range check. 462 // Range check.
463 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset())); 463 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset()));
464 // Runtime throws exception. 464 // Runtime throws exception.
465 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 465 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
466 466
(...skipping 12 matching lines...) Expand all
479 &fall_through, 479 &fall_through,
480 Assembler::kNearJump, 480 Assembler::kNearJump,
481 EAX, // Result register. 481 EAX, // Result register.
482 EBX); 482 EBX);
483 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); 483 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
484 __ ret(); 484 __ ret();
485 __ Bind(&fall_through); 485 __ Bind(&fall_through);
486 } 486 }
487 487
488 488
489 void Intrinsifier::Float64Array_setIndexed(Assembler* assembler) { 489 void Intrinsifier::Float64ArraySetIndexed(Assembler* assembler) {
490 Label fall_through; 490 Label fall_through;
491 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. 491 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index.
492 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array. 492 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array.
493 __ testl(EBX, Immediate(kSmiTagMask)); 493 __ testl(EBX, Immediate(kSmiTagMask));
494 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 494 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
495 // Range check. 495 // Range check.
496 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset())); 496 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset()));
497 // Runtime throws exception. 497 // Runtime throws exception.
498 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 498 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
499 499
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 __ ret(); 1255 __ ret();
1256 __ Bind(&is_zero); 1256 __ Bind(&is_zero);
1257 // Check for negative zero (get the sign bit). 1257 // Check for negative zero (get the sign bit).
1258 __ movmskpd(EAX, XMM0); 1258 __ movmskpd(EAX, XMM0);
1259 __ testl(EAX, Immediate(1)); 1259 __ testl(EAX, Immediate(1));
1260 __ j(NOT_ZERO, &is_true, Assembler::kNearJump); 1260 __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
1261 __ jmp(&is_false, Assembler::kNearJump); 1261 __ jmp(&is_false, Assembler::kNearJump);
1262 } 1262 }
1263 1263
1264 1264
1265 void Intrinsifier::Double_toInt(Assembler* assembler) { 1265 void Intrinsifier::DoubleToInteger(Assembler* assembler) {
1266 __ movl(EAX, Address(ESP, +1 * kWordSize)); 1266 __ movl(EAX, Address(ESP, +1 * kWordSize));
1267 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); 1267 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
1268 __ cvttsd2si(EAX, XMM0); 1268 __ cvttsd2si(EAX, XMM0);
1269 // Overflow is signalled with minint. 1269 // Overflow is signalled with minint.
1270 Label fall_through; 1270 Label fall_through;
1271 // Check for overflow and that it fits into Smi. 1271 // Check for overflow and that it fits into Smi.
1272 __ cmpl(EAX, Immediate(0xC0000000)); 1272 __ cmpl(EAX, Immediate(0xC0000000));
1273 __ j(NEGATIVE, &fall_through, Assembler::kNearJump); 1273 __ j(NEGATIVE, &fall_through, Assembler::kNearJump);
1274 __ SmiTag(EAX); 1274 __ SmiTag(EAX);
1275 __ ret(); 1275 __ ret();
1276 __ Bind(&fall_through); 1276 __ Bind(&fall_through);
1277 } 1277 }
1278 1278
1279 1279
1280 // Argument type is not known 1280 // Argument type is not known
1281 void Intrinsifier::Math_sqrt(Assembler* assembler) { 1281 void Intrinsifier::MathSqrt(Assembler* assembler) {
1282 Label fall_through, is_smi, double_op; 1282 Label fall_through, is_smi, double_op;
1283 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); 1283 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
1284 // Argument is double and is in EAX. 1284 // Argument is double and is in EAX.
1285 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); 1285 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
1286 __ Bind(&double_op); 1286 __ Bind(&double_op);
1287 __ sqrtsd(XMM0, XMM1); 1287 __ sqrtsd(XMM0, XMM1);
1288 const Class& double_class = Class::Handle( 1288 const Class& double_class = Class::Handle(
1289 Isolate::Current()->object_store()->double_class()); 1289 Isolate::Current()->object_store()->double_class());
1290 __ TryAllocate(double_class, 1290 __ TryAllocate(double_class,
1291 &fall_through, 1291 &fall_through,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 __ mull(addr_0); 1335 __ mull(addr_0);
1336 __ addl(EAX, addr_1); 1336 __ addl(EAX, addr_1);
1337 __ adcl(EDX, Immediate(0)); 1337 __ adcl(EDX, Immediate(0));
1338 __ movl(addr_1, EDX); 1338 __ movl(addr_1, EDX);
1339 __ movl(addr_0, EAX); 1339 __ movl(addr_0, EAX);
1340 __ ret(); 1340 __ ret();
1341 } 1341 }
1342 1342
1343 1343
1344 // Identity comparison. 1344 // Identity comparison.
1345 void Intrinsifier::Object_equal(Assembler* assembler) { 1345 void Intrinsifier::ObjectEquals(Assembler* assembler) {
1346 Label is_true; 1346 Label is_true;
1347 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 1347 __ movl(EAX, Address(ESP, + 1 * kWordSize));
1348 __ cmpl(EAX, Address(ESP, + 2 * kWordSize)); 1348 __ cmpl(EAX, Address(ESP, + 2 * kWordSize));
1349 __ j(EQUAL, &is_true, Assembler::kNearJump); 1349 __ j(EQUAL, &is_true, Assembler::kNearJump);
1350 __ LoadObject(EAX, Bool::False()); 1350 __ LoadObject(EAX, Bool::False());
1351 __ ret(); 1351 __ ret();
1352 __ Bind(&is_true); 1352 __ Bind(&is_true);
1353 __ LoadObject(EAX, Bool::True()); 1353 __ LoadObject(EAX, Bool::True());
1354 __ ret(); 1354 __ ret();
1355 } 1355 }
1356 1356
1357 1357
1358 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1358 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1359 Label fall_through; 1359 Label fall_through;
1360 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. 1360 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object.
1361 __ movl(EAX, FieldAddress(EAX, String::hash_offset())); 1361 __ movl(EAX, FieldAddress(EAX, String::hash_offset()));
1362 __ cmpl(EAX, Immediate(0)); 1362 __ cmpl(EAX, Immediate(0));
1363 __ j(EQUAL, &fall_through, Assembler::kNearJump); 1363 __ j(EQUAL, &fall_through, Assembler::kNearJump);
1364 __ ret(); 1364 __ ret();
1365 __ Bind(&fall_through); 1365 __ Bind(&fall_through);
1366 // Hash not yet computed. 1366 // Hash not yet computed.
1367 } 1367 }
1368 1368
1369 1369
1370 void Intrinsifier::String_getLength(Assembler* assembler) { 1370 void Intrinsifier::StringBaseLength(Assembler* assembler) {
1371 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. 1371 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object.
1372 __ movl(EAX, FieldAddress(EAX, String::length_offset())); 1372 __ movl(EAX, FieldAddress(EAX, String::length_offset()));
1373 __ ret(); 1373 __ ret();
1374 } 1374 }
1375 1375
1376 1376
1377 void Intrinsifier::String_codeUnitAt(Assembler* assembler) { 1377 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
1378 Label fall_through, try_two_byte_string; 1378 Label fall_through, try_two_byte_string;
1379 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 1379 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
1380 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // String. 1380 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // String.
1381 __ testl(EBX, Immediate(kSmiTagMask)); 1381 __ testl(EBX, Immediate(kSmiTagMask));
1382 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 1382 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
1383 // Range check. 1383 // Range check.
1384 __ cmpl(EBX, FieldAddress(EAX, String::length_offset())); 1384 __ cmpl(EBX, FieldAddress(EAX, String::length_offset()));
1385 // Runtime throws exception. 1385 // Runtime throws exception.
1386 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 1386 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
1387 __ CompareClassId(EAX, kOneByteStringCid, EDI); 1387 __ CompareClassId(EAX, kOneByteStringCid, EDI);
1388 __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump); 1388 __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
1389 __ SmiUntag(EBX); 1389 __ SmiUntag(EBX);
1390 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset())); 1390 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()));
1391 __ SmiTag(EAX); 1391 __ SmiTag(EAX);
1392 __ ret(); 1392 __ ret();
1393 1393
1394 __ Bind(&try_two_byte_string); 1394 __ Bind(&try_two_byte_string);
1395 __ CompareClassId(EAX, kTwoByteStringCid, EDI); 1395 __ CompareClassId(EAX, kTwoByteStringCid, EDI);
1396 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1396 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1397 ASSERT(kSmiTagShift == 1); 1397 ASSERT(kSmiTagShift == 1);
1398 __ movzxw(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset())); 1398 __ movzxw(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()));
1399 __ SmiTag(EAX); 1399 __ SmiTag(EAX);
1400 __ ret(); 1400 __ ret();
1401 1401
1402 __ Bind(&fall_through); 1402 __ Bind(&fall_through);
1403 } 1403 }
1404 1404
1405 1405
1406 void Intrinsifier::String_getIsEmpty(Assembler* assembler) { 1406 void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
1407 Label is_true; 1407 Label is_true;
1408 // Get length. 1408 // Get length.
1409 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. 1409 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object.
1410 __ movl(EAX, FieldAddress(EAX, String::length_offset())); 1410 __ movl(EAX, FieldAddress(EAX, String::length_offset()));
1411 __ cmpl(EAX, Immediate(Smi::RawValue(0))); 1411 __ cmpl(EAX, Immediate(Smi::RawValue(0)));
1412 __ j(EQUAL, &is_true, Assembler::kNearJump); 1412 __ j(EQUAL, &is_true, Assembler::kNearJump);
1413 __ LoadObject(EAX, Bool::False()); 1413 __ LoadObject(EAX, Bool::False());
1414 __ ret(); 1414 __ ret();
1415 __ Bind(&is_true); 1415 __ Bind(&is_true);
1416 __ LoadObject(EAX, Bool::True()); 1416 __ LoadObject(EAX, Bool::True());
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1607 __ movb(FieldAddress(EAX, EDX, TIMES_1, OneByteString::data_offset()), BL); 1607 __ movb(FieldAddress(EAX, EDX, TIMES_1, OneByteString::data_offset()), BL);
1608 __ incl(EDX); 1608 __ incl(EDX);
1609 __ Bind(&check); 1609 __ Bind(&check);
1610 __ cmpl(EDX, ECX); 1610 __ cmpl(EDX, ECX);
1611 __ j(LESS, &loop, Assembler::kNearJump); 1611 __ j(LESS, &loop, Assembler::kNearJump);
1612 __ ret(); 1612 __ ret();
1613 __ Bind(&fall_through); 1613 __ Bind(&fall_through);
1614 } 1614 }
1615 1615
1616 1616
1617 void Intrinsifier::OneByteString_setAt(Assembler* assembler) { 1617 void Intrinsifier::OneByteStringSetAt(Assembler* assembler) {
1618 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value. 1618 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value.
1619 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. 1619 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index.
1620 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // OneByteString. 1620 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // OneByteString.
1621 __ SmiUntag(EBX); 1621 __ SmiUntag(EBX);
1622 __ SmiUntag(ECX); 1622 __ SmiUntag(ECX);
1623 __ movb(FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()), CL); 1623 __ movb(FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()), CL);
1624 __ ret(); 1624 __ ret();
1625 } 1625 }
1626 1626
1627 1627
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 Isolate::current_tag_offset()); 1747 Isolate::current_tag_offset());
1748 // Set return value to Isolate::current_tag_. 1748 // Set return value to Isolate::current_tag_.
1749 __ movl(EAX, current_tag_addr); 1749 __ movl(EAX, current_tag_addr);
1750 __ ret(); 1750 __ ret();
1751 } 1751 }
1752 1752
1753 #undef __ 1753 #undef __
1754 } // namespace dart 1754 } // namespace dart
1755 1755
1756 #endif // defined TARGET_ARCH_IA32 1756 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm64.cc ('k') | runtime/vm/intrinsifier_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698