| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 END_LEAF_RUNTIME_ENTRY | 100 END_LEAF_RUNTIME_ENTRY |
| 101 | 101 |
| 102 | 102 |
| 103 // Input parameters: | 103 // Input parameters: |
| 104 // ESP : points to return address. | 104 // ESP : points to return address. |
| 105 // EAX : stop message (const char*). | 105 // EAX : stop message (const char*). |
| 106 // Must preserve all registers, except EAX. | 106 // Must preserve all registers, except EAX. |
| 107 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 107 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
| 108 __ EnterCallRuntimeFrame(1 * kWordSize); | 108 __ EnterCallRuntimeFrame(1 * kWordSize); |
| 109 __ movl(Address(ESP, 0), EAX); | 109 __ movl(Address(ESP, 0), EAX); |
| 110 __ CallRuntime(kPrintStopMessageRuntimeEntry); | 110 __ CallRuntime(kPrintStopMessageRuntimeEntry, 1); |
| 111 __ LeaveCallRuntimeFrame(); | 111 __ LeaveCallRuntimeFrame(); |
| 112 __ ret(); | 112 __ ret(); |
| 113 } | 113 } |
| 114 | 114 |
| 115 | 115 |
| 116 // Input parameters: | 116 // Input parameters: |
| 117 // ESP : points to return address. | 117 // ESP : points to return address. |
| 118 // ESP + 4 : address of return value. | 118 // ESP + 4 : address of return value. |
| 119 // EAX : address of first argument in argument array. | 119 // EAX : address of first argument in argument array. |
| 120 // ECX : address of the native function to call. | 120 // ECX : address of the native function to call. |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 | 256 |
| 257 | 257 |
| 258 // Input parameters: | 258 // Input parameters: |
| 259 // EDX: arguments descriptor array. | 259 // EDX: arguments descriptor array. |
| 260 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 260 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 261 const Immediate& raw_null = | 261 const Immediate& raw_null = |
| 262 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 262 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 263 __ EnterStubFrame(); | 263 __ EnterStubFrame(); |
| 264 __ pushl(EDX); // Preserve arguments descriptor array. | 264 __ pushl(EDX); // Preserve arguments descriptor array. |
| 265 __ pushl(raw_null); // Setup space on stack for return value. | 265 __ pushl(raw_null); // Setup space on stack for return value. |
| 266 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 266 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
| 267 __ popl(EAX); // Get Code object result. | 267 __ popl(EAX); // Get Code object result. |
| 268 __ popl(EDX); // Restore arguments descriptor array. | 268 __ popl(EDX); // Restore arguments descriptor array. |
| 269 // Remove the stub frame as we are about to jump to the dart function. | 269 // Remove the stub frame as we are about to jump to the dart function. |
| 270 __ LeaveFrame(); | 270 __ LeaveFrame(); |
| 271 | 271 |
| 272 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); | 272 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); |
| 273 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 273 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 274 __ jmp(ECX); | 274 __ jmp(ECX); |
| 275 } | 275 } |
| 276 | 276 |
| 277 | 277 |
| 278 // Called from a static call only when an invalid code has been entered | 278 // Called from a static call only when an invalid code has been entered |
| 279 // (invalid because its function was optimized or deoptimized). | 279 // (invalid because its function was optimized or deoptimized). |
| 280 // EDX: arguments descriptor array. | 280 // EDX: arguments descriptor array. |
| 281 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 281 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 282 const Immediate& raw_null = | 282 const Immediate& raw_null = |
| 283 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 283 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 284 // Create a stub frame as we are pushing some objects on the stack before | 284 // Create a stub frame as we are pushing some objects on the stack before |
| 285 // calling into the runtime. | 285 // calling into the runtime. |
| 286 __ EnterStubFrame(); | 286 __ EnterStubFrame(); |
| 287 __ pushl(EDX); // Preserve arguments descriptor array. | 287 __ pushl(EDX); // Preserve arguments descriptor array. |
| 288 __ pushl(raw_null); // Setup space on stack for return value. | 288 __ pushl(raw_null); // Setup space on stack for return value. |
| 289 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 289 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
| 290 __ popl(EAX); // Get Code object. | 290 __ popl(EAX); // Get Code object. |
| 291 __ popl(EDX); // Restore arguments descriptor array. | 291 __ popl(EDX); // Restore arguments descriptor array. |
| 292 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 292 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
| 293 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 293 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 294 __ LeaveFrame(); | 294 __ LeaveFrame(); |
| 295 __ jmp(EAX); | 295 __ jmp(EAX); |
| 296 __ int3(); | 296 __ int3(); |
| 297 } | 297 } |
| 298 | 298 |
| 299 | 299 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 350 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 351 __ pushl(Address(ESP, EDI, TIMES_2, (3 * kWordSize))); | 351 __ pushl(Address(ESP, EDI, TIMES_2, (3 * kWordSize))); |
| 352 | 352 |
| 353 __ pushl(ECX); // Pass IC data object. | 353 __ pushl(ECX); // Pass IC data object. |
| 354 __ pushl(EDX); // Pass arguments descriptor array. | 354 __ pushl(EDX); // Pass arguments descriptor array. |
| 355 | 355 |
| 356 // Pass the call's arguments array. | 356 // Pass the call's arguments array. |
| 357 __ movl(EDX, EDI); // Smi-tagged arguments array length. | 357 __ movl(EDX, EDI); // Smi-tagged arguments array length. |
| 358 PushArgumentsArray(assembler); | 358 PushArgumentsArray(assembler); |
| 359 | 359 |
| 360 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); | 360 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); |
| 361 | 361 |
| 362 // Remove arguments. | 362 // Remove arguments. |
| 363 __ Drop(4); | 363 __ Drop(4); |
| 364 __ popl(EAX); // Get result into EAX. | 364 __ popl(EAX); // Get result into EAX. |
| 365 __ LeaveFrame(); | 365 __ LeaveFrame(); |
| 366 __ ret(); | 366 __ ret(); |
| 367 } | 367 } |
| 368 | 368 |
| 369 | 369 |
| 370 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 370 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 intptr_t offset = 0; | 415 intptr_t offset = 0; |
| 416 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { | 416 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { |
| 417 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); | 417 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); |
| 418 __ movups(Address(ESP, offset), xmm_reg); | 418 __ movups(Address(ESP, offset), xmm_reg); |
| 419 offset += kFpuRegisterSize; | 419 offset += kFpuRegisterSize; |
| 420 } | 420 } |
| 421 | 421 |
| 422 __ movl(ECX, ESP); // Preserve saved registers block. | 422 __ movl(ECX, ESP); // Preserve saved registers block. |
| 423 __ ReserveAlignedFrameSpace(1 * kWordSize); | 423 __ ReserveAlignedFrameSpace(1 * kWordSize); |
| 424 __ movl(Address(ESP, 0), ECX); // Start of register block. | 424 __ movl(Address(ESP, 0), ECX); // Start of register block. |
| 425 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); | 425 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1); |
| 426 // Result (EAX) is stack-size (FP - SP) in bytes. | 426 // Result (EAX) is stack-size (FP - SP) in bytes. |
| 427 | 427 |
| 428 if (preserve_result) { | 428 if (preserve_result) { |
| 429 // Restore result into EBX temporarily. | 429 // Restore result into EBX temporarily. |
| 430 __ movl(EBX, Address(EBP, saved_result_slot_from_fp * kWordSize)); | 430 __ movl(EBX, Address(EBP, saved_result_slot_from_fp * kWordSize)); |
| 431 } | 431 } |
| 432 | 432 |
| 433 __ LeaveFrame(); | 433 __ LeaveFrame(); |
| 434 __ popl(EDX); // Preserve return address. | 434 __ popl(EDX); // Preserve return address. |
| 435 __ movl(ESP, EBP); // Discard optimized frame. | 435 __ movl(ESP, EBP); // Discard optimized frame. |
| 436 __ subl(ESP, EAX); // Reserve space for deoptimized frame. | 436 __ subl(ESP, EAX); // Reserve space for deoptimized frame. |
| 437 __ pushl(EDX); // Restore return address. | 437 __ pushl(EDX); // Restore return address. |
| 438 | 438 |
| 439 // Leaf runtime function DeoptimizeFillFrame expects a Dart frame. | 439 // Leaf runtime function DeoptimizeFillFrame expects a Dart frame. |
| 440 __ EnterDartFrame(0); | 440 __ EnterDartFrame(0); |
| 441 if (preserve_result) { | 441 if (preserve_result) { |
| 442 __ pushl(EBX); // Preserve result as first local. | 442 __ pushl(EBX); // Preserve result as first local. |
| 443 } | 443 } |
| 444 __ ReserveAlignedFrameSpace(1 * kWordSize); | 444 __ ReserveAlignedFrameSpace(1 * kWordSize); |
| 445 __ movl(Address(ESP, 0), EBP); // Pass last FP as parameter on stack. | 445 __ movl(Address(ESP, 0), EBP); // Pass last FP as parameter on stack. |
| 446 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); | 446 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); |
| 447 if (preserve_result) { | 447 if (preserve_result) { |
| 448 // Restore result into EBX. | 448 // Restore result into EBX. |
| 449 __ movl(EBX, Address(EBP, kFirstLocalSlotFromFp * kWordSize)); | 449 __ movl(EBX, Address(EBP, kFirstLocalSlotFromFp * kWordSize)); |
| 450 } | 450 } |
| 451 // Code above cannot cause GC. | 451 // Code above cannot cause GC. |
| 452 __ LeaveFrame(); | 452 __ LeaveFrame(); |
| 453 | 453 |
| 454 // Frame is fully rewritten at this point and it is safe to perform a GC. | 454 // Frame is fully rewritten at this point and it is safe to perform a GC. |
| 455 // Materialize any objects that were deferred by FillFrame because they | 455 // Materialize any objects that were deferred by FillFrame because they |
| 456 // require allocation. | 456 // require allocation. |
| 457 __ EnterStubFrame(); | 457 __ EnterStubFrame(); |
| 458 if (preserve_result) { | 458 if (preserve_result) { |
| 459 __ pushl(EBX); // Preserve result, it will be GC-d here. | 459 __ pushl(EBX); // Preserve result, it will be GC-d here. |
| 460 } | 460 } |
| 461 __ pushl(Immediate(Smi::RawValue(0))); // Space for the result. | 461 __ pushl(Immediate(Smi::RawValue(0))); // Space for the result. |
| 462 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry); | 462 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); |
| 463 // Result tells stub how many bytes to remove from the expression stack | 463 // Result tells stub how many bytes to remove from the expression stack |
| 464 // of the bottom-most frame. They were used as materialization arguments. | 464 // of the bottom-most frame. They were used as materialization arguments. |
| 465 __ popl(EBX); | 465 __ popl(EBX); |
| 466 __ SmiUntag(EBX); | 466 __ SmiUntag(EBX); |
| 467 if (preserve_result) { | 467 if (preserve_result) { |
| 468 __ popl(EAX); // Restore result. | 468 __ popl(EAX); // Restore result. |
| 469 } | 469 } |
| 470 __ LeaveFrame(); | 470 __ LeaveFrame(); |
| 471 | 471 |
| 472 __ popl(ECX); // Pop return address. | 472 __ popl(ECX); // Pop return address. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 // Preserve IC data and arguments descriptor. | 504 // Preserve IC data and arguments descriptor. |
| 505 __ pushl(ECX); | 505 __ pushl(ECX); |
| 506 __ pushl(EDX); | 506 __ pushl(EDX); |
| 507 | 507 |
| 508 const Immediate& raw_null = | 508 const Immediate& raw_null = |
| 509 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); | 509 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); |
| 510 __ pushl(raw_null); // Space for the result of the runtime call. | 510 __ pushl(raw_null); // Space for the result of the runtime call. |
| 511 __ pushl(EAX); // Pass receiver. | 511 __ pushl(EAX); // Pass receiver. |
| 512 __ pushl(ECX); // Pass IC data. | 512 __ pushl(ECX); // Pass IC data. |
| 513 __ pushl(EDX); // Pass arguments descriptor. | 513 __ pushl(EDX); // Pass arguments descriptor. |
| 514 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry); | 514 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
| 515 // Discard arguments. | 515 // Discard arguments. |
| 516 __ popl(EAX); | 516 __ popl(EAX); |
| 517 __ popl(EAX); | 517 __ popl(EAX); |
| 518 __ popl(EAX); | 518 __ popl(EAX); |
| 519 __ popl(EAX); // Return value from the runtime call (instructions). | 519 __ popl(EAX); // Return value from the runtime call (instructions). |
| 520 __ popl(EDX); // Restore arguments descriptor. | 520 __ popl(EDX); // Restore arguments descriptor. |
| 521 __ popl(ECX); // Restore IC data. | 521 __ popl(ECX); // Restore IC data. |
| 522 __ LeaveFrame(); | 522 __ LeaveFrame(); |
| 523 | 523 |
| 524 Label lookup; | 524 Label lookup; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 | 655 |
| 656 // Unable to allocate the array using the fast inline code, just call | 656 // Unable to allocate the array using the fast inline code, just call |
| 657 // into the runtime. | 657 // into the runtime. |
| 658 __ Bind(&slow_case); | 658 __ Bind(&slow_case); |
| 659 // Create a stub frame as we are pushing some objects on the stack before | 659 // Create a stub frame as we are pushing some objects on the stack before |
| 660 // calling into the runtime. | 660 // calling into the runtime. |
| 661 __ EnterStubFrame(); | 661 __ EnterStubFrame(); |
| 662 __ pushl(raw_null); // Setup space on stack for return value. | 662 __ pushl(raw_null); // Setup space on stack for return value. |
| 663 __ pushl(EDX); // Array length as Smi. | 663 __ pushl(EDX); // Array length as Smi. |
| 664 __ pushl(ECX); // Element type. | 664 __ pushl(ECX); // Element type. |
| 665 __ CallRuntime(kAllocateArrayRuntimeEntry); | 665 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
| 666 __ popl(EAX); // Pop element type argument. | 666 __ popl(EAX); // Pop element type argument. |
| 667 __ popl(EDX); // Pop array length argument. | 667 __ popl(EDX); // Pop array length argument. |
| 668 __ popl(EAX); // Pop return value from return slot. | 668 __ popl(EAX); // Pop return value from return slot. |
| 669 __ LeaveFrame(); | 669 __ LeaveFrame(); |
| 670 __ ret(); | 670 __ ret(); |
| 671 } | 671 } |
| 672 | 672 |
| 673 | 673 |
| 674 // Input parameters: | 674 // Input parameters: |
| 675 // EDX: Arguments descriptor array. | 675 // EDX: Arguments descriptor array. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 __ cmpl(EAX, raw_null); | 712 __ cmpl(EAX, raw_null); |
| 713 Label function_compiled; | 713 Label function_compiled; |
| 714 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); | 714 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); |
| 715 | 715 |
| 716 // Create a stub frame as we are pushing some objects on the stack before | 716 // Create a stub frame as we are pushing some objects on the stack before |
| 717 // calling into the runtime. | 717 // calling into the runtime. |
| 718 __ EnterStubFrame(); | 718 __ EnterStubFrame(); |
| 719 | 719 |
| 720 __ pushl(EDX); // Preserve arguments descriptor array. | 720 __ pushl(EDX); // Preserve arguments descriptor array. |
| 721 __ pushl(ECX); // Preserve read-only function object argument. | 721 __ pushl(ECX); // Preserve read-only function object argument. |
| 722 __ CallRuntime(kCompileFunctionRuntimeEntry); | 722 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 723 __ popl(ECX); // Restore read-only function object argument in ECX. | 723 __ popl(ECX); // Restore read-only function object argument in ECX. |
| 724 __ popl(EDX); // Restore arguments descriptor array. | 724 __ popl(EDX); // Restore arguments descriptor array. |
| 725 // Restore EAX. | 725 // Restore EAX. |
| 726 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); | 726 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); |
| 727 | 727 |
| 728 // Remove the stub frame as we are about to jump to the closure function. | 728 // Remove the stub frame as we are about to jump to the closure function. |
| 729 __ LeaveFrame(); | 729 __ LeaveFrame(); |
| 730 | 730 |
| 731 __ Bind(&function_compiled); | 731 __ Bind(&function_compiled); |
| 732 // EAX: Code. | 732 // EAX: Code. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 748 // Create a stub frame as we are pushing some objects on the stack before | 748 // Create a stub frame as we are pushing some objects on the stack before |
| 749 // calling into the runtime. | 749 // calling into the runtime. |
| 750 __ EnterStubFrame(); | 750 __ EnterStubFrame(); |
| 751 | 751 |
| 752 __ pushl(raw_null); // Setup space on stack for result from error reporting. | 752 __ pushl(raw_null); // Setup space on stack for result from error reporting. |
| 753 __ pushl(EDX); // Arguments descriptor. | 753 __ pushl(EDX); // Arguments descriptor. |
| 754 // Load smi-tagged arguments array length, including the non-closure. | 754 // Load smi-tagged arguments array length, including the non-closure. |
| 755 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 755 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 756 PushArgumentsArray(assembler); | 756 PushArgumentsArray(assembler); |
| 757 | 757 |
| 758 __ CallRuntime(kInvokeNonClosureRuntimeEntry); | 758 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); |
| 759 // Remove arguments. | 759 // Remove arguments. |
| 760 __ Drop(2); | 760 __ Drop(2); |
| 761 __ popl(EAX); // Get result into EAX. | 761 __ popl(EAX); // Get result into EAX. |
| 762 | 762 |
| 763 // Remove the stub frame as we are about to return. | 763 // Remove the stub frame as we are about to return. |
| 764 __ LeaveFrame(); | 764 __ LeaveFrame(); |
| 765 __ ret(); | 765 __ ret(); |
| 766 } | 766 } |
| 767 | 767 |
| 768 | 768 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 __ ret(); | 997 __ ret(); |
| 998 | 998 |
| 999 __ Bind(&slow_case); | 999 __ Bind(&slow_case); |
| 1000 } | 1000 } |
| 1001 // Create a stub frame as we are pushing some objects on the stack before | 1001 // Create a stub frame as we are pushing some objects on the stack before |
| 1002 // calling into the runtime. | 1002 // calling into the runtime. |
| 1003 __ EnterStubFrame(); | 1003 __ EnterStubFrame(); |
| 1004 __ pushl(raw_null); // Setup space on stack for return value. | 1004 __ pushl(raw_null); // Setup space on stack for return value. |
| 1005 __ SmiTag(EDX); | 1005 __ SmiTag(EDX); |
| 1006 __ pushl(EDX); | 1006 __ pushl(EDX); |
| 1007 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. | 1007 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. |
| 1008 __ popl(EAX); // Pop number of context variables argument. | 1008 __ popl(EAX); // Pop number of context variables argument. |
| 1009 __ popl(EAX); // Pop the new context object. | 1009 __ popl(EAX); // Pop the new context object. |
| 1010 // EAX: new object | 1010 // EAX: new object |
| 1011 // Restore the frame pointer. | 1011 // Restore the frame pointer. |
| 1012 __ LeaveFrame(); | 1012 __ LeaveFrame(); |
| 1013 __ ret(); | 1013 __ ret(); |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); | 1016 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); |
| 1017 | 1017 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 __ j(EQUAL, &L, Assembler::kNearJump); | 1068 __ j(EQUAL, &L, Assembler::kNearJump); |
| 1069 __ ret(); | 1069 __ ret(); |
| 1070 | 1070 |
| 1071 // Handle overflow: Call the runtime leaf function. | 1071 // Handle overflow: Call the runtime leaf function. |
| 1072 __ Bind(&L); | 1072 __ Bind(&L); |
| 1073 // Setup frame, push callee-saved registers. | 1073 // Setup frame, push callee-saved registers. |
| 1074 | 1074 |
| 1075 __ EnterCallRuntimeFrame(1 * kWordSize); | 1075 __ EnterCallRuntimeFrame(1 * kWordSize); |
| 1076 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1076 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
| 1077 __ movl(Address(ESP, 0), EAX); // Push the isolate as the only argument. | 1077 __ movl(Address(ESP, 0), EAX); // Push the isolate as the only argument. |
| 1078 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry); | 1078 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
| 1079 // Restore callee-saved registers, tear down frame. | 1079 // Restore callee-saved registers, tear down frame. |
| 1080 __ LeaveCallRuntimeFrame(); | 1080 __ LeaveCallRuntimeFrame(); |
| 1081 __ ret(); | 1081 __ ret(); |
| 1082 } | 1082 } |
| 1083 | 1083 |
| 1084 | 1084 |
| 1085 // Called for inline allocation of objects. | 1085 // Called for inline allocation of objects. |
| 1086 // Input parameters: | 1086 // Input parameters: |
| 1087 // ESP + 8 : type arguments object (only if class is parameterized). | 1087 // ESP + 8 : type arguments object (only if class is parameterized). |
| 1088 // ESP + 4 : type arguments of instantiator (only if class is parameterized). | 1088 // ESP + 4 : type arguments of instantiator (only if class is parameterized). |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1238 __ EnterStubFrame(); | 1238 __ EnterStubFrame(); |
| 1239 __ pushl(raw_null); // Setup space on stack for return value. | 1239 __ pushl(raw_null); // Setup space on stack for return value. |
| 1240 __ PushObject(cls); // Push class of object to be allocated. | 1240 __ PushObject(cls); // Push class of object to be allocated. |
| 1241 if (is_cls_parameterized) { | 1241 if (is_cls_parameterized) { |
| 1242 __ pushl(EAX); // Push type arguments of object to be allocated. | 1242 __ pushl(EAX); // Push type arguments of object to be allocated. |
| 1243 __ pushl(EDX); // Push type arguments of instantiator. | 1243 __ pushl(EDX); // Push type arguments of instantiator. |
| 1244 } else { | 1244 } else { |
| 1245 __ pushl(raw_null); // Push null type arguments. | 1245 __ pushl(raw_null); // Push null type arguments. |
| 1246 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1246 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
| 1247 } | 1247 } |
| 1248 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. | 1248 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. |
| 1249 __ popl(EAX); // Pop argument (instantiator). | 1249 __ popl(EAX); // Pop argument (instantiator). |
| 1250 __ popl(EAX); // Pop argument (type arguments of object). | 1250 __ popl(EAX); // Pop argument (type arguments of object). |
| 1251 __ popl(EAX); // Pop argument (class of object). | 1251 __ popl(EAX); // Pop argument (class of object). |
| 1252 __ popl(EAX); // Pop result (newly allocated object). | 1252 __ popl(EAX); // Pop result (newly allocated object). |
| 1253 // EAX: new object | 1253 // EAX: new object |
| 1254 // Restore the frame pointer. | 1254 // Restore the frame pointer. |
| 1255 __ LeaveFrame(); | 1255 __ LeaveFrame(); |
| 1256 __ ret(); | 1256 __ ret(); |
| 1257 } | 1257 } |
| 1258 | 1258 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1372 __ PushObject(func); | 1372 __ PushObject(func); |
| 1373 if (is_implicit_instance_closure) { | 1373 if (is_implicit_instance_closure) { |
| 1374 __ pushl(EAX); // Receiver. | 1374 __ pushl(EAX); // Receiver. |
| 1375 } | 1375 } |
| 1376 if (has_type_arguments) { | 1376 if (has_type_arguments) { |
| 1377 __ pushl(ECX); // Push type arguments of closure to be allocated. | 1377 __ pushl(ECX); // Push type arguments of closure to be allocated. |
| 1378 } else { | 1378 } else { |
| 1379 __ pushl(raw_null); // Push null type arguments. | 1379 __ pushl(raw_null); // Push null type arguments. |
| 1380 } | 1380 } |
| 1381 if (is_implicit_instance_closure) { | 1381 if (is_implicit_instance_closure) { |
| 1382 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry); | 1382 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); |
| 1383 __ popl(EAX); // Pop argument (type arguments of object). | 1383 __ popl(EAX); // Pop argument (type arguments of object). |
| 1384 __ popl(EAX); // Pop receiver. | 1384 __ popl(EAX); // Pop receiver. |
| 1385 } else { | 1385 } else { |
| 1386 ASSERT(func.IsNonImplicitClosureFunction()); | 1386 ASSERT(func.IsNonImplicitClosureFunction()); |
| 1387 __ CallRuntime(kAllocateClosureRuntimeEntry); | 1387 __ CallRuntime(kAllocateClosureRuntimeEntry, 2); |
| 1388 __ popl(EAX); // Pop argument (type arguments of object). | 1388 __ popl(EAX); // Pop argument (type arguments of object). |
| 1389 } | 1389 } |
| 1390 __ popl(EAX); // Pop function object. | 1390 __ popl(EAX); // Pop function object. |
| 1391 __ popl(EAX); | 1391 __ popl(EAX); |
| 1392 // EAX: new object | 1392 // EAX: new object |
| 1393 // Restore the frame pointer. | 1393 // Restore the frame pointer. |
| 1394 __ LeaveFrame(); | 1394 __ LeaveFrame(); |
| 1395 __ ret(); | 1395 __ ret(); |
| 1396 } | 1396 } |
| 1397 | 1397 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1416 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1416 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1417 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. | 1417 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. |
| 1418 __ pushl(EAX); // Receiver. | 1418 __ pushl(EAX); // Receiver. |
| 1419 __ pushl(ECX); // IC data array. | 1419 __ pushl(ECX); // IC data array. |
| 1420 __ pushl(EDX); // Arguments descriptor array. | 1420 __ pushl(EDX); // Arguments descriptor array. |
| 1421 | 1421 |
| 1422 __ movl(EDX, EDI); | 1422 __ movl(EDX, EDI); |
| 1423 // EDX: Smi-tagged arguments array length. | 1423 // EDX: Smi-tagged arguments array length. |
| 1424 PushArgumentsArray(assembler); | 1424 PushArgumentsArray(assembler); |
| 1425 | 1425 |
| 1426 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); | 1426 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4); |
| 1427 | 1427 |
| 1428 // Remove arguments. | 1428 // Remove arguments. |
| 1429 __ Drop(4); | 1429 __ Drop(4); |
| 1430 __ popl(EAX); // Get result into EAX. | 1430 __ popl(EAX); // Get result into EAX. |
| 1431 | 1431 |
| 1432 // Remove the stub frame as we are about to return. | 1432 // Remove the stub frame as we are about to return. |
| 1433 __ LeaveFrame(); | 1433 __ LeaveFrame(); |
| 1434 __ ret(); | 1434 __ ret(); |
| 1435 } | 1435 } |
| 1436 | 1436 |
| 1437 | 1437 |
| 1438 // Cannot use function object from ICData as it may be the inlined | 1438 // Cannot use function object from ICData as it may be the inlined |
| 1439 // function and not the top-scope function. | 1439 // function and not the top-scope function. |
| 1440 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { | 1440 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { |
| 1441 Register ic_reg = ECX; | 1441 Register ic_reg = ECX; |
| 1442 Register func_reg = EDI; | 1442 Register func_reg = EDI; |
| 1443 if (FLAG_trace_optimized_ic_calls) { | 1443 if (FLAG_trace_optimized_ic_calls) { |
| 1444 __ EnterStubFrame(); | 1444 __ EnterStubFrame(); |
| 1445 __ pushl(func_reg); // Preserve | 1445 __ pushl(func_reg); // Preserve |
| 1446 __ pushl(ic_reg); // Preserve. | 1446 __ pushl(ic_reg); // Preserve. |
| 1447 __ pushl(ic_reg); // Argument. | 1447 __ pushl(ic_reg); // Argument. |
| 1448 __ pushl(func_reg); // Argument. | 1448 __ pushl(func_reg); // Argument. |
| 1449 __ CallRuntime(kTraceICCallRuntimeEntry); | 1449 __ CallRuntime(kTraceICCallRuntimeEntry, 2); |
| 1450 __ popl(EAX); // Discard argument; | 1450 __ popl(EAX); // Discard argument; |
| 1451 __ popl(EAX); // Discard argument; | 1451 __ popl(EAX); // Discard argument; |
| 1452 __ popl(ic_reg); // Restore. | 1452 __ popl(ic_reg); // Restore. |
| 1453 __ popl(func_reg); // Restore. | 1453 __ popl(func_reg); // Restore. |
| 1454 __ LeaveFrame(); | 1454 __ LeaveFrame(); |
| 1455 } | 1455 } |
| 1456 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); | 1456 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); |
| 1457 } | 1457 } |
| 1458 | 1458 |
| 1459 | 1459 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1497 | 1497 |
| 1498 // Check single stepping. | 1498 // Check single stepping. |
| 1499 Label not_stepping; | 1499 Label not_stepping; |
| 1500 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1500 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
| 1501 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 1501 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
| 1502 __ cmpl(EAX, Immediate(0)); | 1502 __ cmpl(EAX, Immediate(0)); |
| 1503 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); | 1503 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); |
| 1504 | 1504 |
| 1505 __ EnterStubFrame(); | 1505 __ EnterStubFrame(); |
| 1506 __ pushl(ECX); | 1506 __ pushl(ECX); |
| 1507 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1507 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1508 __ popl(ECX); | 1508 __ popl(ECX); |
| 1509 __ LeaveFrame(); | 1509 __ LeaveFrame(); |
| 1510 __ Bind(¬_stepping); | 1510 __ Bind(¬_stepping); |
| 1511 | 1511 |
| 1512 // ECX: IC data object (preserved). | 1512 // ECX: IC data object (preserved). |
| 1513 // Load arguments descriptor into EDX. | 1513 // Load arguments descriptor into EDX. |
| 1514 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); | 1514 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); |
| 1515 // Loop that checks if there is an IC data match. | 1515 // Loop that checks if there is an IC data match. |
| 1516 Label loop, update, test, found, get_class_id_as_smi; | 1516 Label loop, update, test, found, get_class_id_as_smi; |
| 1517 // ECX: IC data object (preserved). | 1517 // ECX: IC data object (preserved). |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1576 __ EnterStubFrame(); | 1576 __ EnterStubFrame(); |
| 1577 __ pushl(EDX); // Preserve arguments descriptor array. | 1577 __ pushl(EDX); // Preserve arguments descriptor array. |
| 1578 __ pushl(ECX); // Preserve IC data object. | 1578 __ pushl(ECX); // Preserve IC data object. |
| 1579 __ pushl(raw_null); // Setup space on stack for result (target code object). | 1579 __ pushl(raw_null); // Setup space on stack for result (target code object). |
| 1580 // Push call arguments. | 1580 // Push call arguments. |
| 1581 for (intptr_t i = 0; i < num_args; i++) { | 1581 for (intptr_t i = 0; i < num_args; i++) { |
| 1582 __ movl(EBX, Address(EAX, -kWordSize * i)); | 1582 __ movl(EBX, Address(EAX, -kWordSize * i)); |
| 1583 __ pushl(EBX); | 1583 __ pushl(EBX); |
| 1584 } | 1584 } |
| 1585 __ pushl(ECX); // Pass IC data object. | 1585 __ pushl(ECX); // Pass IC data object. |
| 1586 __ CallRuntime(handle_ic_miss); | 1586 __ CallRuntime(handle_ic_miss, num_args + 1); |
| 1587 // Remove the call arguments pushed earlier, including the IC data object. | 1587 // Remove the call arguments pushed earlier, including the IC data object. |
| 1588 for (intptr_t i = 0; i < num_args + 1; i++) { | 1588 for (intptr_t i = 0; i < num_args + 1; i++) { |
| 1589 __ popl(EAX); | 1589 __ popl(EAX); |
| 1590 } | 1590 } |
| 1591 __ popl(EAX); // Pop returned code object into EAX (null if not found). | 1591 __ popl(EAX); // Pop returned code object into EAX (null if not found). |
| 1592 __ popl(ECX); // Restore IC data array. | 1592 __ popl(ECX); // Restore IC data array. |
| 1593 __ popl(EDX); // Restore arguments descriptor array. | 1593 __ popl(EDX); // Restore arguments descriptor array. |
| 1594 __ LeaveFrame(); | 1594 __ LeaveFrame(); |
| 1595 Label call_target_function; | 1595 Label call_target_function; |
| 1596 __ cmpl(EAX, raw_null); | 1596 __ cmpl(EAX, raw_null); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 #endif // DEBUG | 1733 #endif // DEBUG |
| 1734 // Check single stepping. | 1734 // Check single stepping. |
| 1735 Label not_stepping; | 1735 Label not_stepping; |
| 1736 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1736 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
| 1737 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 1737 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
| 1738 __ cmpl(EAX, Immediate(0)); | 1738 __ cmpl(EAX, Immediate(0)); |
| 1739 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); | 1739 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); |
| 1740 | 1740 |
| 1741 __ EnterStubFrame(); | 1741 __ EnterStubFrame(); |
| 1742 __ pushl(ECX); | 1742 __ pushl(ECX); |
| 1743 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1743 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1744 __ popl(ECX); | 1744 __ popl(ECX); |
| 1745 __ LeaveFrame(); | 1745 __ LeaveFrame(); |
| 1746 __ Bind(¬_stepping); | 1746 __ Bind(¬_stepping); |
| 1747 | 1747 |
| 1748 // ECX: IC data object (preserved). | 1748 // ECX: IC data object (preserved). |
| 1749 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); | 1749 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); |
| 1750 // EBX: ic_data_array with entries: target functions and count. | 1750 // EBX: ic_data_array with entries: target functions and count. |
| 1751 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); | 1751 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); |
| 1752 // EBX: points directly to the first ic data array element. | 1752 // EBX: points directly to the first ic data array element. |
| 1753 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; | 1753 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1765 Label target_is_compiled; | 1765 Label target_is_compiled; |
| 1766 // Get function and call it, if possible. | 1766 // Get function and call it, if possible. |
| 1767 __ movl(EDI, Address(EBX, target_offset)); | 1767 __ movl(EDI, Address(EBX, target_offset)); |
| 1768 __ movl(EAX, FieldAddress(EDI, Function::code_offset())); | 1768 __ movl(EAX, FieldAddress(EDI, Function::code_offset())); |
| 1769 __ cmpl(EAX, raw_null); | 1769 __ cmpl(EAX, raw_null); |
| 1770 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump); | 1770 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump); |
| 1771 __ EnterStubFrame(); | 1771 __ EnterStubFrame(); |
| 1772 __ pushl(EDI); // Preserve target function. | 1772 __ pushl(EDI); // Preserve target function. |
| 1773 __ pushl(ECX); // Preserve IC data object. | 1773 __ pushl(ECX); // Preserve IC data object. |
| 1774 __ pushl(EDI); // Pass function. | 1774 __ pushl(EDI); // Pass function. |
| 1775 __ CallRuntime(kCompileFunctionRuntimeEntry); | 1775 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1776 __ popl(EAX); // Discard argument. | 1776 __ popl(EAX); // Discard argument. |
| 1777 __ popl(ECX); // Restore IC data object. | 1777 __ popl(ECX); // Restore IC data object. |
| 1778 __ popl(EDI); // Restore target function. | 1778 __ popl(EDI); // Restore target function. |
| 1779 __ LeaveFrame(); | 1779 __ LeaveFrame(); |
| 1780 __ movl(EAX, FieldAddress(EDI, Function::code_offset())); | 1780 __ movl(EAX, FieldAddress(EDI, Function::code_offset())); |
| 1781 | 1781 |
| 1782 __ Bind(&target_is_compiled); | 1782 __ Bind(&target_is_compiled); |
| 1783 // EAX: Target code. | 1783 // EAX: Target code. |
| 1784 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 1784 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
| 1785 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1785 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1800 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { | 1800 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { |
| 1801 __ EnterStubFrame(); | 1801 __ EnterStubFrame(); |
| 1802 // Save runtime args. | 1802 // Save runtime args. |
| 1803 __ pushl(ECX); | 1803 __ pushl(ECX); |
| 1804 __ pushl(EDX); | 1804 __ pushl(EDX); |
| 1805 // Room for result. Debugger stub returns address of the | 1805 // Room for result. Debugger stub returns address of the |
| 1806 // unpatched runtime stub. | 1806 // unpatched runtime stub. |
| 1807 const Immediate& raw_null = | 1807 const Immediate& raw_null = |
| 1808 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1808 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1809 __ pushl(raw_null); // Room for result. | 1809 __ pushl(raw_null); // Room for result. |
| 1810 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry); | 1810 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
| 1811 __ popl(EAX); // Address of original stub. | 1811 __ popl(EAX); // Address of original stub. |
| 1812 __ popl(EDX); // Restore arguments. | 1812 __ popl(EDX); // Restore arguments. |
| 1813 __ popl(ECX); | 1813 __ popl(ECX); |
| 1814 __ LeaveFrame(); | 1814 __ LeaveFrame(); |
| 1815 __ jmp(EAX); // Jump to original stub. | 1815 __ jmp(EAX); // Jump to original stub. |
| 1816 } | 1816 } |
| 1817 | 1817 |
| 1818 | 1818 |
| 1819 // ECX: ICData (unoptimized static call). | 1819 // ECX: ICData (unoptimized static call). |
| 1820 // TOS(0): return address (Dart code). | 1820 // TOS(0): return address (Dart code). |
| 1821 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1821 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
| 1822 // Create a stub frame as we are pushing some objects on the stack before | 1822 // Create a stub frame as we are pushing some objects on the stack before |
| 1823 // calling into the runtime. | 1823 // calling into the runtime. |
| 1824 __ EnterStubFrame(); | 1824 __ EnterStubFrame(); |
| 1825 __ pushl(ECX); // Preserve ICData for unoptimized call. | 1825 __ pushl(ECX); // Preserve ICData for unoptimized call. |
| 1826 const Immediate& raw_null = | 1826 const Immediate& raw_null = |
| 1827 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1827 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1828 __ pushl(raw_null); // Room for result. | 1828 __ pushl(raw_null); // Room for result. |
| 1829 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1829 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); |
| 1830 __ popl(EAX); // Code object. | 1830 __ popl(EAX); // Code object. |
| 1831 __ popl(ECX); // Restore ICData. | 1831 __ popl(ECX); // Restore ICData. |
| 1832 __ LeaveFrame(); | 1832 __ LeaveFrame(); |
| 1833 | 1833 |
| 1834 // Load arguments descriptor into EDX. | 1834 // Load arguments descriptor into EDX. |
| 1835 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); | 1835 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); |
| 1836 // Now call the static function. The breakpoint handler function | 1836 // Now call the static function. The breakpoint handler function |
| 1837 // ensures that the call target is compiled. | 1837 // ensures that the call target is compiled. |
| 1838 // Note that we can't just jump to the CallStatic function stub | 1838 // Note that we can't just jump to the CallStatic function stub |
| 1839 // here since that stub would patch the call site with the | 1839 // here since that stub would patch the call site with the |
| 1840 // static function address. | 1840 // static function address. |
| 1841 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); | 1841 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); |
| 1842 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1842 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1843 __ jmp(ECX); | 1843 __ jmp(ECX); |
| 1844 } | 1844 } |
| 1845 | 1845 |
| 1846 | 1846 |
| 1847 // TOS(0): return address (Dart code). | 1847 // TOS(0): return address (Dart code). |
| 1848 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1848 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
| 1849 // Create a stub frame as we are pushing some objects on the stack before | 1849 // Create a stub frame as we are pushing some objects on the stack before |
| 1850 // calling into the runtime. | 1850 // calling into the runtime. |
| 1851 __ EnterStubFrame(); | 1851 __ EnterStubFrame(); |
| 1852 __ pushl(EAX); | 1852 __ pushl(EAX); |
| 1853 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); | 1853 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0); |
| 1854 __ popl(EAX); | 1854 __ popl(EAX); |
| 1855 __ LeaveFrame(); | 1855 __ LeaveFrame(); |
| 1856 | 1856 |
| 1857 // Instead of returning to the patched Dart function, emulate the | 1857 // Instead of returning to the patched Dart function, emulate the |
| 1858 // smashed return code pattern and return to the function's caller. | 1858 // smashed return code pattern and return to the function's caller. |
| 1859 __ popl(ECX); // Discard return address to patched dart code. | 1859 __ popl(ECX); // Discard return address to patched dart code. |
| 1860 // Execute function epilog code that was smashed in the Dart code. | 1860 // Execute function epilog code that was smashed in the Dart code. |
| 1861 __ LeaveFrame(); | 1861 __ LeaveFrame(); |
| 1862 __ ret(); | 1862 __ ret(); |
| 1863 } | 1863 } |
| 1864 | 1864 |
| 1865 | 1865 |
| 1866 // ECX: Inline cache data array. | 1866 // ECX: Inline cache data array. |
| 1867 // TOS(0): return address (Dart code). | 1867 // TOS(0): return address (Dart code). |
| 1868 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1868 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
| 1869 // Create a stub frame as we are pushing some objects on the stack before | 1869 // Create a stub frame as we are pushing some objects on the stack before |
| 1870 // calling into the runtime. | 1870 // calling into the runtime. |
| 1871 __ EnterStubFrame(); | 1871 __ EnterStubFrame(); |
| 1872 __ pushl(ECX); | 1872 __ pushl(ECX); |
| 1873 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); | 1873 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); |
| 1874 __ popl(ECX); | 1874 __ popl(ECX); |
| 1875 __ LeaveFrame(); | 1875 __ LeaveFrame(); |
| 1876 | 1876 |
| 1877 // Find out which dispatch stub to call. | 1877 // Find out which dispatch stub to call. |
| 1878 Label test_two, test_three, test_four; | 1878 Label test_two, test_three, test_four; |
| 1879 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); | 1879 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); |
| 1880 __ cmpl(EBX, Immediate(1)); | 1880 __ cmpl(EBX, Immediate(1)); |
| 1881 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump); | 1881 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump); |
| 1882 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); | 1882 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); |
| 1883 __ Bind(&test_two); | 1883 __ Bind(&test_two); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2116 __ Bind(&update_ic_data); | 2116 __ Bind(&update_ic_data); |
| 2117 | 2117 |
| 2118 // ECX: ICData | 2118 // ECX: ICData |
| 2119 __ movl(EAX, Address(ESP, 1 * kWordSize)); | 2119 __ movl(EAX, Address(ESP, 1 * kWordSize)); |
| 2120 __ movl(EDI, Address(ESP, 2 * kWordSize)); | 2120 __ movl(EDI, Address(ESP, 2 * kWordSize)); |
| 2121 __ EnterStubFrame(); | 2121 __ EnterStubFrame(); |
| 2122 __ pushl(EDI); // arg 0 | 2122 __ pushl(EDI); // arg 0 |
| 2123 __ pushl(EAX); // arg 1 | 2123 __ pushl(EAX); // arg 1 |
| 2124 __ PushObject(Symbols::EqualOperator()); // Target's name. | 2124 __ PushObject(Symbols::EqualOperator()); // Target's name. |
| 2125 __ pushl(ECX); // ICData | 2125 __ pushl(ECX); // ICData |
| 2126 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); | 2126 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4); |
| 2127 __ Drop(4); | 2127 __ Drop(4); |
| 2128 __ LeaveFrame(); | 2128 __ LeaveFrame(); |
| 2129 | 2129 |
| 2130 __ jmp(&compute_result, Assembler::kNearJump); | 2130 __ jmp(&compute_result, Assembler::kNearJump); |
| 2131 } | 2131 } |
| 2132 | 2132 |
| 2133 | 2133 |
| 2134 // Calls to the runtime to optimize the given function. | 2134 // Calls to the runtime to optimize the given function. |
| 2135 // EDI: function to be reoptimized. | 2135 // EDI: function to be reoptimized. |
| 2136 // EDX: argument descriptor (preserved). | 2136 // EDX: argument descriptor (preserved). |
| 2137 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 2137 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
| 2138 const Immediate& raw_null = | 2138 const Immediate& raw_null = |
| 2139 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 2139 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 2140 __ EnterStubFrame(); | 2140 __ EnterStubFrame(); |
| 2141 __ pushl(EDX); | 2141 __ pushl(EDX); |
| 2142 __ pushl(raw_null); // Setup space on stack for return value. | 2142 __ pushl(raw_null); // Setup space on stack for return value. |
| 2143 __ pushl(EDI); | 2143 __ pushl(EDI); |
| 2144 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 2144 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
| 2145 __ popl(EAX); // Discard argument. | 2145 __ popl(EAX); // Discard argument. |
| 2146 __ popl(EAX); // Get Code object | 2146 __ popl(EAX); // Get Code object |
| 2147 __ popl(EDX); // Restore argument descriptor. | 2147 __ popl(EDX); // Restore argument descriptor. |
| 2148 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 2148 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
| 2149 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 2149 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 2150 __ LeaveFrame(); | 2150 __ LeaveFrame(); |
| 2151 __ jmp(EAX); | 2151 __ jmp(EAX); |
| 2152 __ int3(); | 2152 __ int3(); |
| 2153 } | 2153 } |
| 2154 | 2154 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2204 | 2204 |
| 2205 __ Bind(&check_bigint); | 2205 __ Bind(&check_bigint); |
| 2206 __ CompareClassId(left, kBigintCid, temp); | 2206 __ CompareClassId(left, kBigintCid, temp); |
| 2207 __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); | 2207 __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); |
| 2208 __ CompareClassId(right, kBigintCid, temp); | 2208 __ CompareClassId(right, kBigintCid, temp); |
| 2209 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 2209 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 2210 __ EnterFrame(0); | 2210 __ EnterFrame(0); |
| 2211 __ ReserveAlignedFrameSpace(2 * kWordSize); | 2211 __ ReserveAlignedFrameSpace(2 * kWordSize); |
| 2212 __ movl(Address(ESP, 1 * kWordSize), left); | 2212 __ movl(Address(ESP, 1 * kWordSize), left); |
| 2213 __ movl(Address(ESP, 0 * kWordSize), right); | 2213 __ movl(Address(ESP, 0 * kWordSize), right); |
| 2214 __ CallRuntime(kBigintCompareRuntimeEntry); | 2214 __ CallRuntime(kBigintCompareRuntimeEntry, 2); |
| 2215 // Result in EAX, 0 means equal. | 2215 // Result in EAX, 0 means equal. |
| 2216 __ LeaveFrame(); | 2216 __ LeaveFrame(); |
| 2217 __ cmpl(EAX, Immediate(0)); | 2217 __ cmpl(EAX, Immediate(0)); |
| 2218 __ jmp(&done); | 2218 __ jmp(&done); |
| 2219 | 2219 |
| 2220 __ Bind(&reference_compare); | 2220 __ Bind(&reference_compare); |
| 2221 __ cmpl(left, right); | 2221 __ cmpl(left, right); |
| 2222 __ Bind(&done); | 2222 __ Bind(&done); |
| 2223 } | 2223 } |
| 2224 | 2224 |
| 2225 | 2225 |
| 2226 // Called only from unoptimized code. All relevant registers have been saved. | 2226 // Called only from unoptimized code. All relevant registers have been saved. |
| 2227 // TOS + 0: return address | 2227 // TOS + 0: return address |
| 2228 // TOS + 1: right argument. | 2228 // TOS + 1: right argument. |
| 2229 // TOS + 2: left argument. | 2229 // TOS + 2: left argument. |
| 2230 // Returns ZF set. | 2230 // Returns ZF set. |
| 2231 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( | 2231 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( |
| 2232 Assembler* assembler) { | 2232 Assembler* assembler) { |
| 2233 // Check single stepping. | 2233 // Check single stepping. |
| 2234 Label not_stepping; | 2234 Label not_stepping; |
| 2235 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 2235 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
| 2236 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 2236 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
| 2237 __ cmpl(EAX, Immediate(0)); | 2237 __ cmpl(EAX, Immediate(0)); |
| 2238 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); | 2238 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); |
| 2239 | 2239 |
| 2240 __ EnterStubFrame(); | 2240 __ EnterStubFrame(); |
| 2241 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 2241 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 2242 __ LeaveFrame(); | 2242 __ LeaveFrame(); |
| 2243 __ Bind(¬_stepping); | 2243 __ Bind(¬_stepping); |
| 2244 | 2244 |
| 2245 const Register left = EAX; | 2245 const Register left = EAX; |
| 2246 const Register right = EDX; | 2246 const Register right = EDX; |
| 2247 const Register temp = ECX; | 2247 const Register temp = ECX; |
| 2248 __ movl(left, Address(ESP, 2 * kWordSize)); | 2248 __ movl(left, Address(ESP, 2 * kWordSize)); |
| 2249 __ movl(right, Address(ESP, 1 * kWordSize)); | 2249 __ movl(right, Address(ESP, 1 * kWordSize)); |
| 2250 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2250 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2251 __ ret(); | 2251 __ ret(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2272 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2272 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2273 __ popl(temp); | 2273 __ popl(temp); |
| 2274 __ popl(right); | 2274 __ popl(right); |
| 2275 __ popl(left); | 2275 __ popl(left); |
| 2276 __ ret(); | 2276 __ ret(); |
| 2277 } | 2277 } |
| 2278 | 2278 |
| 2279 } // namespace dart | 2279 } // namespace dart |
| 2280 | 2280 |
| 2281 #endif // defined TARGET_ARCH_IA32 | 2281 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |