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

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

Issue 13588005: Fix issue 9644: object stores become large pieces of code if heap tracing is turned on; jumps aroun… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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 | « no previous file | runtime/vm/intrinsifier_x64.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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 __ j(EQUAL, &checked_ok, Assembler::kNearJump); 202 __ j(EQUAL, &checked_ok, Assembler::kNearJump);
203 203
204 __ movl(EBX, Address(ESP, + 3 * kWordSize)); // Array. 204 __ movl(EBX, Address(ESP, + 3 * kWordSize)); // Array.
205 __ movl(EBX, FieldAddress(EBX, type_args_field_offset)); 205 __ movl(EBX, FieldAddress(EBX, type_args_field_offset));
206 // EBX: Type arguments of array. 206 // EBX: Type arguments of array.
207 __ cmpl(EBX, raw_null); 207 __ cmpl(EBX, raw_null);
208 __ j(EQUAL, &checked_ok, Assembler::kNearJump); 208 __ j(EQUAL, &checked_ok, Assembler::kNearJump);
209 // Check if it's dynamic. 209 // Check if it's dynamic.
210 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs. 210 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs.
211 __ CompareClassId(EBX, kTypeArgumentsCid, EAX); 211 __ CompareClassId(EBX, kTypeArgumentsCid, EAX);
212 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 212 __ j(NOT_EQUAL, &fall_through);
213 // Get type at index 0. 213 // Get type at index 0.
214 __ movl(EAX, FieldAddress(EBX, TypeArguments::type_at_offset(0))); 214 __ movl(EAX, FieldAddress(EBX, TypeArguments::type_at_offset(0)));
215 __ CompareObject(EAX, Type::ZoneHandle(Type::DynamicType())); 215 __ CompareObject(EAX, Type::ZoneHandle(Type::DynamicType()));
216 __ j(EQUAL, &checked_ok, Assembler::kNearJump); 216 __ j(EQUAL, &checked_ok, Assembler::kNearJump);
217 // Check for int and num. 217 // Check for int and num.
218 __ testl(EDI, Immediate(kSmiTagMask)); // Value is Smi? 218 __ testl(EDI, Immediate(kSmiTagMask)); // Value is Smi?
219 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi value. 219 __ j(NOT_ZERO, &fall_through); // Non-smi value.
220 __ CompareObject(EAX, Type::ZoneHandle(Type::IntType())); 220 __ CompareObject(EAX, Type::ZoneHandle(Type::IntType()));
221 __ j(EQUAL, &checked_ok, Assembler::kNearJump); 221 __ j(EQUAL, &checked_ok, Assembler::kNearJump);
222 __ CompareObject(EAX, Type::ZoneHandle(Type::Number())); 222 __ CompareObject(EAX, Type::ZoneHandle(Type::Number()));
223 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 223 __ j(NOT_EQUAL, &fall_through);
224 __ Bind(&checked_ok); 224 __ Bind(&checked_ok);
225 } 225 }
226 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. 226 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index.
227 __ testl(EBX, Immediate(kSmiTagMask)); 227 __ testl(EBX, Immediate(kSmiTagMask));
228 // Index not Smi. 228 // Index not Smi.
229 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); 229 __ j(NOT_ZERO, &fall_through);
230 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array. 230 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array.
231 // Range check. 231 // Range check.
232 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); 232 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset()));
233 // Runtime throws exception. 233 // Runtime throws exception.
234 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 234 __ j(ABOVE_EQUAL, &fall_through);
235 // Note that EBX is Smi, i.e, times 2. 235 // Note that EBX is Smi, i.e, times 2.
236 ASSERT(kSmiTagShift == 1); 236 ASSERT(kSmiTagShift == 1);
237 // Destroy ECX as we will not continue in the function. 237 // Destroy ECX as we will not continue in the function.
238 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value. 238 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value.
239 __ StoreIntoObject(EAX, 239 __ StoreIntoObject(EAX,
240 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), 240 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()),
241 ECX); 241 ECX);
242 // Caller is responsible of preserving the value if necessary. 242 // Caller is responsible of preserving the value if necessary.
243 __ ret(); 243 __ ret();
244 __ Bind(&fall_through); 244 __ Bind(&fall_through);
(...skipping 19 matching lines...) Expand all
264 Isolate* isolate = Isolate::Current(); 264 Isolate* isolate = Isolate::Current();
265 Heap* heap = isolate->heap(); 265 Heap* heap = isolate->heap();
266 266
267 __ movl(EAX, Address::Absolute(heap->TopAddress())); 267 __ movl(EAX, Address::Absolute(heap->TopAddress()));
268 __ leal(EBX, Address(EAX, fixed_size)); 268 __ leal(EBX, Address(EAX, fixed_size));
269 269
270 // Check if the allocation fits into the remaining space. 270 // Check if the allocation fits into the remaining space.
271 // EAX: potential new backing array object start. 271 // EAX: potential new backing array object start.
272 // EBX: potential next object start. 272 // EBX: potential next object start.
273 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); 273 __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
274 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 274 __ j(ABOVE_EQUAL, &fall_through);
275 275
276 // Successfully allocated the object(s), now update top to point to 276 // Successfully allocated the object(s), now update top to point to
277 // next object start and initialize the object. 277 // next object start and initialize the object.
278 __ movl(Address::Absolute(heap->TopAddress()), EBX); 278 __ movl(Address::Absolute(heap->TopAddress()), EBX);
279 __ addl(EAX, Immediate(kHeapObjectTag)); 279 __ addl(EAX, Immediate(kHeapObjectTag));
280 280
281 // Initialize the tags. 281 // Initialize the tags.
282 // EAX: new growable array object start as a tagged pointer. 282 // EAX: new growable array object start as a tagged pointer.
283 const Class& cls = Class::Handle( 283 const Class& cls = Class::Handle(
284 isolate->object_store()->growable_object_array_class()); 284 isolate->object_store()->growable_object_array_class());
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 // Set value into growable object array at specified index. 359 // Set value into growable object array at specified index.
360 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). 360 // On stack: growable array (+3), index (+2), value (+1), return-address (+0).
361 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { 361 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
362 if (FLAG_enable_type_checks) { 362 if (FLAG_enable_type_checks) {
363 return false; 363 return false;
364 } 364 }
365 Label fall_through; 365 Label fall_through;
366 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. 366 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index.
367 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. 367 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray.
368 __ testl(EBX, Immediate(kSmiTagMask)); 368 __ testl(EBX, Immediate(kSmiTagMask));
369 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 369 __ j(NOT_ZERO, &fall_through); // Non-smi index.
370 // Range check using _length field. 370 // Range check using _length field.
371 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 371 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
372 // Runtime throws exception. 372 // Runtime throws exception.
373 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 373 __ j(ABOVE_EQUAL, &fall_through);
374 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. 374 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data.
375 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. 375 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value.
376 // Note that EBX is Smi, i.e, times 2. 376 // Note that EBX is Smi, i.e, times 2.
377 ASSERT(kSmiTagShift == 1); 377 ASSERT(kSmiTagShift == 1);
378 __ StoreIntoObject(EAX, 378 __ StoreIntoObject(EAX,
379 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), 379 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()),
380 EDI); 380 EDI);
381 __ ret(); 381 __ ret();
382 __ Bind(&fall_through); 382 __ Bind(&fall_through);
383 return false; 383 return false;
(...skipping 21 matching lines...) Expand all
405 // Set data of growable object array. 405 // Set data of growable object array.
406 // On stack: growable array (+2), data (+1), return-address (+0). 406 // On stack: growable array (+2), data (+1), return-address (+0).
407 bool Intrinsifier::GrowableArray_setData(Assembler* assembler) { 407 bool Intrinsifier::GrowableArray_setData(Assembler* assembler) {
408 if (FLAG_enable_type_checks) { 408 if (FLAG_enable_type_checks) {
409 return false; 409 return false;
410 } 410 }
411 Label fall_through; 411 Label fall_through;
412 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Data. 412 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Data.
413 // Check that data is an ObjectArray. 413 // Check that data is an ObjectArray.
414 __ testl(EBX, Immediate(kSmiTagMask)); 414 __ testl(EBX, Immediate(kSmiTagMask));
415 __ j(ZERO, &fall_through, Assembler::kNearJump); // Data is Smi. 415 __ j(ZERO, &fall_through); // Data is Smi.
416 __ CompareClassId(EBX, kArrayCid, EAX); 416 __ CompareClassId(EBX, kArrayCid, EAX);
417 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 417 __ j(NOT_EQUAL, &fall_through);
418 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array. 418 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array.
419 __ StoreIntoObject(EAX, 419 __ StoreIntoObject(EAX,
420 FieldAddress(EAX, GrowableObjectArray::data_offset()), 420 FieldAddress(EAX, GrowableObjectArray::data_offset()),
421 EBX); 421 EBX);
422 __ ret(); 422 __ ret();
423 __ Bind(&fall_through); 423 __ Bind(&fall_through);
424 return false; 424 return false;
425 } 425 }
426 426
427 427
428 // Add an element to growable array if it doesn't need to grow, otherwise 428 // Add an element to growable array if it doesn't need to grow, otherwise
429 // call into regular code. 429 // call into regular code.
430 // On stack: growable array (+2), value (+1), return-address (+0). 430 // On stack: growable array (+2), value (+1), return-address (+0).
431 bool Intrinsifier::GrowableArray_add(Assembler* assembler) { 431 bool Intrinsifier::GrowableArray_add(Assembler* assembler) {
432 // In checked mode we need to type-check the incoming argument. 432 // In checked mode we need to type-check the incoming argument.
433 if (FLAG_enable_type_checks) return false; 433 if (FLAG_enable_type_checks) return false;
434 Label fall_through; 434 Label fall_through;
435 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. 435 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
436 __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 436 __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
437 // EBX: length. 437 // EBX: length.
438 __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset())); 438 __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset()));
439 // EDI: data. 439 // EDI: data.
440 // Compare length with capacity. 440 // Compare length with capacity.
441 __ cmpl(EBX, FieldAddress(EDI, Array::length_offset())); 441 __ cmpl(EBX, FieldAddress(EDI, Array::length_offset()));
442 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Must grow data. 442 __ j(EQUAL, &fall_through); // Must grow data.
443 const Immediate& value_one = 443 const Immediate& value_one =
444 Immediate(reinterpret_cast<int32_t>(Smi::New(1))); 444 Immediate(reinterpret_cast<int32_t>(Smi::New(1)));
445 // len = len + 1; 445 // len = len + 1;
446 __ addl(FieldAddress(EAX, GrowableObjectArray::length_offset()), value_one); 446 __ addl(FieldAddress(EAX, GrowableObjectArray::length_offset()), value_one);
447 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Value 447 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Value
448 ASSERT(kSmiTagShift == 1); 448 ASSERT(kSmiTagShift == 1);
449 __ StoreIntoObject(EDI, 449 __ StoreIntoObject(EDI,
450 FieldAddress(EDI, EBX, TIMES_2, Array::data_offset()), 450 FieldAddress(EDI, EBX, TIMES_2, Array::data_offset()),
451 EAX); 451 EAX);
452 const Immediate& raw_null = 452 const Immediate& raw_null =
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 __ SmiTag(EAX); 1495 __ SmiTag(EAX);
1496 __ movl(FieldAddress(EBX, String::hash_offset()), EAX); 1496 __ movl(FieldAddress(EBX, String::hash_offset()), EAX);
1497 __ ret(); 1497 __ ret();
1498 return true; 1498 return true;
1499 } 1499 }
1500 1500
1501 #undef __ 1501 #undef __
1502 } // namespace dart 1502 } // namespace dart
1503 1503
1504 #endif // defined TARGET_ARCH_IA32 1504 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intrinsifier_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698