Chromium Code Reviews| 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 __ SmiUntag(EBX); | |
|
srdjan
2012/06/06 23:30:00
You could skip untagging EBX and use TIMES_1.
cshapiro
2012/06/06 23:43:07
Thanks! Done.
| |
| 479 __ movsxw(EAX, FieldAddress(EAX, | |
| 480 EBX, | |
| 481 TIMES_2, | |
| 482 Int16Array::data_offset())); | |
| 483 __ SmiTag(EAX); | |
| 484 __ ret(); | |
| 485 __ Bind(&fall_through); | |
| 486 return false; | |
| 487 } | |
| 488 | |
| 489 | |
| 490 bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) { | |
| 491 Label fall_through; | |
| 492 TestByteArrayIndex(assembler, &fall_through); | |
| 493 __ SmiUntag(EBX); | |
|
srdjan
2012/06/06 23:30:00
ditto
cshapiro
2012/06/06 23:43:07
Done.
| |
| 494 __ movzxw(EAX, FieldAddress(EAX, | |
| 495 EBX, | |
| 496 TIMES_2, | |
| 497 Uint16Array::data_offset())); | |
| 498 __ SmiTag(EAX); | |
| 499 __ ret(); | |
| 500 __ Bind(&fall_through); | |
| 501 return false; | |
| 502 } | |
| 503 | |
| 504 | |
| 505 bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) { | |
| 506 return false; | |
| 507 } | |
| 508 | |
| 509 | |
| 510 bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) { | |
| 511 return false; | |
| 512 } | |
| 513 | |
| 514 | |
| 420 // Tests if two top most arguments are smis, jumps to label not_smi if not. | 515 // Tests if two top most arguments are smis, jumps to label not_smi if not. |
| 421 // Topmost argument is in EAX. | 516 // Topmost argument is in EAX. |
| 422 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { | 517 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { |
| 423 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 518 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 424 __ movl(EBX, Address(ESP, + 2 * kWordSize)); | 519 __ movl(EBX, Address(ESP, + 2 * kWordSize)); |
| 425 __ orl(EBX, EAX); | 520 __ orl(EBX, EAX); |
| 426 __ testl(EBX, Immediate(kSmiTagMask)); | 521 __ testl(EBX, Immediate(kSmiTagMask)); |
| 427 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); | 522 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); |
| 428 } | 523 } |
| 429 | 524 |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1258 __ Bind(&is_true); | 1353 __ Bind(&is_true); |
| 1259 __ LoadObject(EAX, bool_true); | 1354 __ LoadObject(EAX, bool_true); |
| 1260 __ ret(); | 1355 __ ret(); |
| 1261 return true; | 1356 return true; |
| 1262 } | 1357 } |
| 1263 | 1358 |
| 1264 #undef __ | 1359 #undef __ |
| 1265 } // namespace dart | 1360 } // namespace dart |
| 1266 | 1361 |
| 1267 #endif // defined TARGET_ARCH_IA32 | 1362 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |