Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 __ popl(EAX); // Get Code object. | 387 __ popl(EAX); // Get Code object. |
| 388 __ popl(EDX); // Restore arguments descriptor array. | 388 __ popl(EDX); // Restore arguments descriptor array. |
| 389 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 389 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
| 390 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 390 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 391 __ LeaveFrame(); | 391 __ LeaveFrame(); |
| 392 __ jmp(EAX); | 392 __ jmp(EAX); |
| 393 __ int3(); | 393 __ int3(); |
| 394 } | 394 } |
| 395 | 395 |
| 396 | 396 |
| 397 // Called from object allocate instruction when the allocation stub has been | 397 // Called from object or array allocate instruction when the allocation stub has |
| 398 // disabled. | 398 // been disabled. |
| 399 // EDX: if called for array, the length (preserved). | |
| 400 // ECX: if called for array, the element type (preserved). | |
| 399 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 401 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
| 400 const Immediate& raw_null = | 402 const Immediate& raw_null = |
| 401 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 403 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 402 __ EnterStubFrame(); | 404 __ EnterStubFrame(); |
| 405 __ pushl(EDX); // Preserve length. | |
| 406 __ pushl(ECX); // Preserve element type. | |
|
srdjan
2014/09/25 17:42:53
For non-arays, EDX and ECX can contain non-object,
koda
2014/09/25 21:49:25
Done.
| |
| 403 __ pushl(raw_null); // Setup space on stack for return value. | 407 __ pushl(raw_null); // Setup space on stack for return value. |
| 404 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 408 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
| 405 __ popl(EAX); // Get Code object. | 409 __ popl(EAX); // Get Code object. |
| 410 __ popl(ECX); // Restore element type. | |
| 411 __ popl(EDX); // Restore length. | |
| 406 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 412 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
| 407 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 413 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 408 __ LeaveFrame(); | 414 __ LeaveFrame(); |
| 409 __ jmp(EAX); | 415 __ jmp(EAX); |
| 410 __ int3(); | 416 __ int3(); |
| 411 } | 417 } |
| 412 | 418 |
| 413 | 419 |
| 414 // Input parameters: | 420 // Input parameters: |
| 415 // EDX: smi-tagged argument count, may be zero. | 421 // EDX: smi-tagged argument count, may be zero. |
| 416 // EBP[kParamEndSlotFromFp + 1]: last argument. | 422 // EBP[kParamEndSlotFromFp + 1]: last argument. |
| 417 // Uses EAX, EBX, ECX, EDX. | 423 // Uses EAX, EBX, ECX, EDX. |
| 418 static void PushArgumentsArray(Assembler* assembler) { | 424 static void PushArgumentsArray(Assembler* assembler) { |
| 419 const Immediate& raw_null = | 425 const Immediate& raw_null = |
| 420 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 426 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 421 StubCode* stub_code = Isolate::Current()->stub_code(); | 427 StubCode* stub_code = Isolate::Current()->stub_code(); |
| 422 | 428 |
| 423 // Allocate array to store arguments of caller. | 429 // Allocate array to store arguments of caller. |
| 424 __ movl(ECX, raw_null); // Null element type for raw Array. | 430 __ movl(ECX, raw_null); // Null element type for raw Array. |
| 425 __ call(&stub_code->AllocateArrayLabel()); | 431 const Code& array_stub = Code::Handle(stub_code->GetAllocateArrayStub()); |
| 432 const ExternalLabel array_label(array_stub.EntryPoint()); | |
| 433 __ call(&array_label); | |
| 426 __ SmiUntag(EDX); | 434 __ SmiUntag(EDX); |
| 427 // EAX: newly allocated array. | 435 // EAX: newly allocated array. |
| 428 // EDX: length of the array (was preserved by the stub). | 436 // EDX: length of the array (was preserved by the stub). |
| 429 __ pushl(EAX); // Array is in EAX and on top of stack. | 437 __ pushl(EAX); // Array is in EAX and on top of stack. |
| 430 __ leal(EBX, Address(EBP, EDX, TIMES_4, kParamEndSlotFromFp * kWordSize)); | 438 __ leal(EBX, Address(EBP, EDX, TIMES_4, kParamEndSlotFromFp * kWordSize)); |
| 431 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); | 439 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); |
| 432 // EBX: address of first argument on stack. | 440 // EBX: address of first argument on stack. |
| 433 // ECX: address of first argument in array. | 441 // ECX: address of first argument in array. |
| 434 Label loop, loop_condition; | 442 Label loop, loop_condition; |
| 435 __ jmp(&loop_condition, Assembler::kNearJump); | 443 __ jmp(&loop_condition, Assembler::kNearJump); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 __ jmp(EBX); | 611 __ jmp(EBX); |
| 604 } | 612 } |
| 605 | 613 |
| 606 | 614 |
| 607 // Called for inline allocation of arrays. | 615 // Called for inline allocation of arrays. |
| 608 // Input parameters: | 616 // Input parameters: |
| 609 // EDX : Array length as Smi (must be preserved). | 617 // EDX : Array length as Smi (must be preserved). |
| 610 // ECX : array element type (either NULL or an instantiated type). | 618 // ECX : array element type (either NULL or an instantiated type). |
| 611 // Uses EAX, EBX, ECX, EDI as temporary registers. | 619 // Uses EAX, EBX, ECX, EDI as temporary registers. |
| 612 // The newly allocated object is returned in EAX. | 620 // The newly allocated object is returned in EAX. |
| 613 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { | 621 void StubCode::GeneratePatchableAllocateArrayStub(Assembler* assembler, |
| 622 uword* entry_patch_offset, uword* patch_code_pc_offset) { | |
| 623 *entry_patch_offset = assembler->CodeSize(); | |
| 614 Label slow_case; | 624 Label slow_case; |
| 615 const Immediate& raw_null = | 625 const Immediate& raw_null = |
| 616 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 626 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 617 | 627 |
| 618 // Compute the size to be allocated, it is based on the array length | 628 // Compute the size to be allocated, it is based on the array length |
| 619 // and is computed as: | 629 // and is computed as: |
| 620 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). | 630 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). |
| 621 // Assert that length is a Smi. | 631 // Assert that length is a Smi. |
| 622 __ testl(EDX, Immediate(kSmiTagMask)); | 632 __ testl(EDX, Immediate(kSmiTagMask)); |
| 623 if (FLAG_use_slow_path) { | 633 if (FLAG_use_slow_path) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 731 __ EnterStubFrame(); | 741 __ EnterStubFrame(); |
| 732 __ pushl(raw_null); // Setup space on stack for return value. | 742 __ pushl(raw_null); // Setup space on stack for return value. |
| 733 __ pushl(EDX); // Array length as Smi. | 743 __ pushl(EDX); // Array length as Smi. |
| 734 __ pushl(ECX); // Element type. | 744 __ pushl(ECX); // Element type. |
| 735 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 745 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
| 736 __ popl(EAX); // Pop element type argument. | 746 __ popl(EAX); // Pop element type argument. |
| 737 __ popl(EDX); // Pop array length argument (preserved). | 747 __ popl(EDX); // Pop array length argument (preserved). |
| 738 __ popl(EAX); // Pop return value from return slot. | 748 __ popl(EAX); // Pop return value from return slot. |
| 739 __ LeaveFrame(); | 749 __ LeaveFrame(); |
| 740 __ ret(); | 750 __ ret(); |
| 751 // Emit function patching code. This will be swapped with the first 5 bytes | |
| 752 // at entry point. | |
| 753 *patch_code_pc_offset = assembler->CodeSize(); | |
| 754 StubCode* stub_code = Isolate::Current()->stub_code(); | |
| 755 __ jmp(&stub_code->FixAllocationStubTargetLabel()); | |
| 741 } | 756 } |
| 742 | 757 |
| 743 | 758 |
| 744 // Called when invoking dart code from C++ (VM code). | 759 // Called when invoking dart code from C++ (VM code). |
| 745 // Input parameters: | 760 // Input parameters: |
| 746 // ESP : points to return address. | 761 // ESP : points to return address. |
| 747 // ESP + 4 : entrypoint of the dart function to call. | 762 // ESP + 4 : entrypoint of the dart function to call. |
| 748 // ESP + 8 : arguments descriptor array. | 763 // ESP + 8 : arguments descriptor array. |
| 749 // ESP + 12 : arguments array. | 764 // ESP + 12 : arguments array. |
| 750 // ESP + 16 : new context containing the current isolate pointer. | 765 // ESP + 16 : new context containing the current isolate pointer. |
| (...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2050 const Register temp = ECX; | 2065 const Register temp = ECX; |
| 2051 __ movl(left, Address(ESP, 2 * kWordSize)); | 2066 __ movl(left, Address(ESP, 2 * kWordSize)); |
| 2052 __ movl(right, Address(ESP, 1 * kWordSize)); | 2067 __ movl(right, Address(ESP, 1 * kWordSize)); |
| 2053 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2068 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2054 __ ret(); | 2069 __ ret(); |
| 2055 } | 2070 } |
| 2056 | 2071 |
| 2057 } // namespace dart | 2072 } // namespace dart |
| 2058 | 2073 |
| 2059 #endif // defined TARGET_ARCH_IA32 | 2074 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |