| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 return false; | 410 return false; |
| 411 } | 411 } |
| 412 __ movl(EAX, Address(ESP, + 2 * kWordSize)); | 412 __ movl(EAX, Address(ESP, + 2 * kWordSize)); |
| 413 __ movl(EBX, Address(ESP, + 1 * kWordSize)); | 413 __ movl(EBX, Address(ESP, + 1 * kWordSize)); |
| 414 __ movl(FieldAddress(EAX, GrowableObjectArray::data_offset()), EBX); | 414 __ movl(FieldAddress(EAX, GrowableObjectArray::data_offset()), EBX); |
| 415 __ ret(); | 415 __ ret(); |
| 416 return true; | 416 return true; |
| 417 } | 417 } |
| 418 | 418 |
| 419 | 419 |
| 420 // Gets the length of a ByteArray. |
| 421 bool Intrinsifier::ByteArrayBase_getLength(Assembler* assembler) { |
| 422 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 423 __ movl(EAX, FieldAddress(EAX, ByteArray::length_offset())); |
| 424 __ ret(); |
| 425 return true; |
| 426 } |
| 427 |
| 428 |
| 429 // Assumes the first argument is a byte array, tests if the second |
| 430 // argument is a smi, tests if the smi is within bounds of the array |
| 431 // length, and jumps to label fall_through if any test fails. Leaves |
| 432 // the second argument in EBX. |
| 433 static void TestByteArrayIndex(Assembler* assembler, Label* fall_through) { |
| 434 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Array. |
| 435 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. |
| 436 __ testl(EBX, Immediate(kSmiTagMask)); |
| 437 __ j(NOT_ZERO, fall_through, Assembler::kNearJump); // Non-smi index. |
| 438 // Range check. |
| 439 __ cmpl(EBX, FieldAddress(EAX, ByteArray::length_offset())); |
| 440 // Runtime throws exception. |
| 441 __ j(ABOVE_EQUAL, fall_through, Assembler::kNearJump); |
| 442 } |
| 443 |
| 444 |
| 445 bool Intrinsifier::Int8Array_getIndexed(Assembler* assembler) { |
| 446 Label fall_through; |
| 447 TestByteArrayIndex(assembler, &fall_through); |
| 448 __ SmiUntag(EBX); |
| 449 __ movsxb(EAX, FieldAddress(EAX, |
| 450 EBX, |
| 451 TIMES_1, |
| 452 Int8Array::data_offset())); |
| 453 __ SmiTag(EAX); |
| 454 __ ret(); |
| 455 __ Bind(&fall_through); |
| 456 return false; |
| 457 } |
| 458 |
| 459 |
| 460 bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) { |
| 461 Label fall_through; |
| 462 TestByteArrayIndex(assembler, &fall_through); |
| 463 __ SmiUntag(EBX); |
| 464 __ movzxb(EAX, FieldAddress(EAX, |
| 465 EBX, |
| 466 TIMES_1, |
| 467 Uint8Array::data_offset())); |
| 468 __ SmiTag(EAX); |
| 469 __ ret(); |
| 470 __ Bind(&fall_through); |
| 471 return false; |
| 472 } |
| 473 |
| 474 |
| 475 bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) { |
| 476 Label fall_through; |
| 477 TestByteArrayIndex(assembler, &fall_through); |
| 478 __ movsxw(EAX, FieldAddress(EAX, |
| 479 EBX, |
| 480 TIMES_1, |
| 481 Int16Array::data_offset())); |
| 482 __ SmiTag(EAX); |
| 483 __ ret(); |
| 484 __ Bind(&fall_through); |
| 485 return false; |
| 486 } |
| 487 |
| 488 |
| 489 bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) { |
| 490 Label fall_through; |
| 491 TestByteArrayIndex(assembler, &fall_through); |
| 492 __ movzxw(EAX, FieldAddress(EAX, |
| 493 EBX, |
| 494 TIMES_1, |
| 495 Uint16Array::data_offset())); |
| 496 __ SmiTag(EAX); |
| 497 __ ret(); |
| 498 __ Bind(&fall_through); |
| 499 return false; |
| 500 } |
| 501 |
| 502 |
| 503 bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) { |
| 504 return false; |
| 505 } |
| 506 |
| 507 |
| 508 bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) { |
| 509 return false; |
| 510 } |
| 511 |
| 512 |
| 420 // Tests if two top most arguments are smis, jumps to label not_smi if not. | 513 // Tests if two top most arguments are smis, jumps to label not_smi if not. |
| 421 // Topmost argument is in EAX. | 514 // Topmost argument is in EAX. |
| 422 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { | 515 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { |
| 423 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 516 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 424 __ movl(EBX, Address(ESP, + 2 * kWordSize)); | 517 __ movl(EBX, Address(ESP, + 2 * kWordSize)); |
| 425 __ orl(EBX, EAX); | 518 __ orl(EBX, EAX); |
| 426 __ testl(EBX, Immediate(kSmiTagMask)); | 519 __ testl(EBX, Immediate(kSmiTagMask)); |
| 427 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); | 520 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); |
| 428 } | 521 } |
| 429 | 522 |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 __ Bind(&is_true); | 1351 __ Bind(&is_true); |
| 1259 __ LoadObject(EAX, bool_true); | 1352 __ LoadObject(EAX, bool_true); |
| 1260 __ ret(); | 1353 __ ret(); |
| 1261 return true; | 1354 return true; |
| 1262 } | 1355 } |
| 1263 | 1356 |
| 1264 #undef __ | 1357 #undef __ |
| 1265 } // namespace dart | 1358 } // namespace dart |
| 1266 | 1359 |
| 1267 #endif // defined TARGET_ARCH_IA32 | 1360 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |