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

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

Issue 1192103004: VM: New calling convention for generated code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fixed comments Created 5 years, 3 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
« no previous file with comments | « runtime/vm/stub_code_arm64.cc ('k') | runtime/vm/stub_code_mips.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 #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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments))); 73 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments)));
74 if (OS::ActivationFrameAlignment() > 1) { 74 if (OS::ActivationFrameAlignment() > 1) {
75 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 75 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
76 } 76 }
77 77
78 // Pass NativeArguments structure by value and call runtime. 78 // Pass NativeArguments structure by value and call runtime.
79 __ movl(Address(ESP, thread_offset), THR); // Set thread in NativeArgs. 79 __ movl(Address(ESP, thread_offset), THR); // Set thread in NativeArgs.
80 // There are no runtime calls to closures, so we do not need to set the tag 80 // There are no runtime calls to closures, so we do not need to set the tag
81 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. 81 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
82 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. 82 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments.
83 __ leal(EAX, Address(EBP, EDX, TIMES_4, 1 * kWordSize)); // Compute argv. 83 // Compute argv.
84 __ leal(EAX, Address(EBP, EDX, TIMES_4, kParamEndSlotFromFp * kWordSize));
84 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. 85 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments.
85 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. 86 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument.
86 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. 87 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments.
87 __ call(ECX); 88 __ call(ECX);
88 89
89 // Mark that the isolate is executing Dart code. EDI is callee saved. 90 // Mark that the isolate is executing Dart code. EDI is callee saved.
90 __ movl(Address(EDI, Isolate::vm_tag_offset()), 91 __ movl(Address(EDI, Isolate::vm_tag_offset()),
91 Immediate(VMTag::kDartTagId)); 92 Immediate(VMTag::kDartTagId));
92 93
93 // Reset exit frame information in Isolate structure. 94 // Reset exit frame information in Isolate structure.
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 // - Materialize objects that require allocation (e.g. Double instances). 363 // - Materialize objects that require allocation (e.g. Double instances).
363 // GC can occur only after frame is fully rewritten. 364 // GC can occur only after frame is fully rewritten.
364 // Stack after EnterDartFrame(0) below: 365 // Stack after EnterDartFrame(0) below:
365 // +------------------+ 366 // +------------------+
366 // | PC marker | <- TOS 367 // | PC marker | <- TOS
367 // +------------------+ 368 // +------------------+
368 // | Saved FP | <- FP of stub 369 // | Saved FP | <- FP of stub
369 // +------------------+ 370 // +------------------+
370 // | return-address | (deoptimization point) 371 // | return-address | (deoptimization point)
371 // +------------------+ 372 // +------------------+
373 // | Saved CODE_REG |
374 // +------------------+
372 // | ... | <- SP of optimized frame 375 // | ... | <- SP of optimized frame
373 // 376 //
374 // Parts of the code cannot GC, part of the code can GC. 377 // Parts of the code cannot GC, part of the code can GC.
375 static void GenerateDeoptimizationSequence(Assembler* assembler, 378 static void GenerateDeoptimizationSequence(Assembler* assembler,
376 bool preserve_result) { 379 DeoptStubKind kind) {
377 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. 380 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
378 __ EnterDartFrame(0); 381 __ EnterDartFrame(0);
379 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry 382 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
380 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. 383 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
381 const intptr_t saved_result_slot_from_fp = 384 const intptr_t saved_result_slot_from_fp =
382 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - EAX); 385 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - EAX);
383 // Result in EAX is preserved as part of pushing all registers below. 386 // Result in EAX is preserved as part of pushing all registers below.
384 387
385 // Push registers in their enumeration order: lowest register number at 388 // Push registers in their enumeration order: lowest register number at
386 // lowest address. 389 // lowest address.
387 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) { 390 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
388 __ pushl(static_cast<Register>(i)); 391 if (i == CODE_REG) {
392 // Save the original value of CODE_REG pushed before invoking this stub
393 // instead of the value used to call this stub.
394 __ pushl(Address(EBP, 2 * kWordSize));
395 } else {
396 __ pushl(static_cast<Register>(i));
397 }
389 } 398 }
390 __ subl(ESP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize)); 399 __ subl(ESP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize));
391 intptr_t offset = 0; 400 intptr_t offset = 0;
392 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { 401 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
393 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); 402 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
394 __ movups(Address(ESP, offset), xmm_reg); 403 __ movups(Address(ESP, offset), xmm_reg);
395 offset += kFpuRegisterSize; 404 offset += kFpuRegisterSize;
396 } 405 }
397 406
398 __ movl(ECX, ESP); // Preserve saved registers block. 407 __ movl(ECX, ESP); // Preserve saved registers block.
399 __ ReserveAlignedFrameSpace(1 * kWordSize); 408 __ ReserveAlignedFrameSpace(2 * kWordSize);
400 __ movl(Address(ESP, 0), ECX); // Start of register block. 409 __ movl(Address(ESP, 0 * kWordSize), ECX); // Start of register block.
401 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1); 410 __ movl(Address(ESP, 1 * kWordSize), Immediate(kind == kLazyDeopt ? 1 : 0));
411 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2);
402 // Result (EAX) is stack-size (FP - SP) in bytes. 412 // Result (EAX) is stack-size (FP - SP) in bytes.
403 413
414 const bool preserve_result = (kind == kLazyDeopt);
404 if (preserve_result) { 415 if (preserve_result) {
405 // Restore result into EBX temporarily. 416 // Restore result into EBX temporarily.
406 __ movl(EBX, Address(EBP, saved_result_slot_from_fp * kWordSize)); 417 __ movl(EBX, Address(EBP, saved_result_slot_from_fp * kWordSize));
407 } 418 }
408 419
409 __ LeaveFrame(); 420 __ LeaveFrame();
410 __ popl(EDX); // Preserve return address. 421 __ popl(EDX); // Preserve return address.
411 __ movl(ESP, EBP); // Discard optimized frame. 422 __ movl(ESP, EBP); // Discard optimized frame.
412 __ subl(ESP, EAX); // Reserve space for deoptimized frame. 423 __ subl(ESP, EAX); // Reserve space for deoptimized frame.
413 __ pushl(EDX); // Restore return address. 424 __ pushl(EDX); // Restore return address.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 464
454 465
455 // TOS: return address + call-instruction-size (5 bytes). 466 // TOS: return address + call-instruction-size (5 bytes).
456 // EAX: result, must be preserved 467 // EAX: result, must be preserved
457 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) { 468 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
458 // Correct return address to point just after the call that is being 469 // Correct return address to point just after the call that is being
459 // deoptimized. 470 // deoptimized.
460 __ popl(EBX); 471 __ popl(EBX);
461 __ subl(EBX, Immediate(CallPattern::pattern_length_in_bytes())); 472 __ subl(EBX, Immediate(CallPattern::pattern_length_in_bytes()));
462 __ pushl(EBX); 473 __ pushl(EBX);
463 GenerateDeoptimizationSequence(assembler, true); // Preserve EAX. 474 GenerateDeoptimizationSequence(assembler, kLazyDeopt);
464 } 475 }
465 476
466 477
467 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 478 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
468 GenerateDeoptimizationSequence(assembler, false); // Don't preserve EAX. 479 GenerateDeoptimizationSequence(assembler, kEagerDeopt);
469 } 480 }
470 481
471 482
472 static void GenerateDispatcherCode(Assembler* assembler, 483 static void GenerateDispatcherCode(Assembler* assembler,
473 Label* call_target_function) { 484 Label* call_target_function) {
474 __ Comment("NoSuchMethodDispatch"); 485 __ Comment("NoSuchMethodDispatch");
475 // When lazily generated invocation dispatchers are disabled, the 486 // When lazily generated invocation dispatchers are disabled, the
476 // miss-handler may return null. 487 // miss-handler may return null.
477 const Immediate& raw_null = 488 const Immediate& raw_null =
478 Immediate(reinterpret_cast<intptr_t>(Object::null())); 489 Immediate(reinterpret_cast<intptr_t>(Object::null()));
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 __ popl(EDX); // Pop array length argument (preserved). 688 __ popl(EDX); // Pop array length argument (preserved).
678 __ popl(EAX); // Pop return value from return slot. 689 __ popl(EAX); // Pop return value from return slot.
679 __ LeaveFrame(); 690 __ LeaveFrame();
680 __ ret(); 691 __ ret();
681 } 692 }
682 693
683 694
684 // Called when invoking dart code from C++ (VM code). 695 // Called when invoking dart code from C++ (VM code).
685 // Input parameters: 696 // Input parameters:
686 // ESP : points to return address. 697 // ESP : points to return address.
687 // ESP + 4 : entrypoint of the dart function to call. 698 // ESP + 4 : code object of the dart function to call.
688 // ESP + 8 : arguments descriptor array. 699 // ESP + 8 : arguments descriptor array.
689 // ESP + 12 : arguments array. 700 // ESP + 12 : arguments array.
690 // ESP + 16 : current thread. 701 // ESP + 16 : current thread.
691 // Uses EAX, EDX, ECX, EDI as temporary registers. 702 // Uses EAX, EDX, ECX, EDI as temporary registers.
692 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { 703 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
693 const intptr_t kEntryPointOffset = 2 * kWordSize; 704 const intptr_t kTargetCodeOffset = 2 * kWordSize;
694 const intptr_t kArgumentsDescOffset = 3 * kWordSize; 705 const intptr_t kArgumentsDescOffset = 3 * kWordSize;
695 const intptr_t kArgumentsOffset = 4 * kWordSize; 706 const intptr_t kArgumentsOffset = 4 * kWordSize;
696 const intptr_t kThreadOffset = 5 * kWordSize; 707 const intptr_t kThreadOffset = 5 * kWordSize;
697 708
698 // Save frame pointer coming in. 709 // Save frame pointer coming in.
699 __ EnterFrame(0); 710 __ EnterFrame(0);
700 711
712 // Push code object to PC marker slot.
713 __ movl(EAX, Address(EBP, kThreadOffset));
714 __ pushl(Address(EAX, Thread::invoke_dart_code_stub_offset()));
715
701 // Save C++ ABI callee-saved registers. 716 // Save C++ ABI callee-saved registers.
702 __ pushl(EBX); 717 __ pushl(EBX);
703 __ pushl(ESI); 718 __ pushl(ESI);
704 __ pushl(EDI); 719 __ pushl(EDI);
705 720
706 // Set up THR, which caches the current thread in Dart code. 721 // Set up THR, which caches the current thread in Dart code.
707 __ movl(THR, Address(EBP, kThreadOffset)); 722 __ movl(THR, EAX);
708 __ LoadIsolate(EDI); 723 __ LoadIsolate(EDI);
709 724
710 // Save the current VMTag on the stack. 725 // Save the current VMTag on the stack.
711 __ movl(ECX, Address(EDI, Isolate::vm_tag_offset())); 726 __ movl(ECX, Address(EDI, Isolate::vm_tag_offset()));
712 __ pushl(ECX); 727 __ pushl(ECX);
713 728
714 // Mark that the isolate is executing Dart code. 729 // Mark that the isolate is executing Dart code.
715 __ movl(Address(EDI, Isolate::vm_tag_offset()), 730 __ movl(Address(EDI, Isolate::vm_tag_offset()),
716 Immediate(VMTag::kDartTagId)); 731 Immediate(VMTag::kDartTagId));
717 732
718 // Save top resource and top exit frame info. Use EDX as a temporary register. 733 // Save top resource and top exit frame info. Use EDX as a temporary register.
719 // StackFrameIterator reads the top exit frame info saved in this frame. 734 // StackFrameIterator reads the top exit frame info saved in this frame.
720 __ movl(EDX, Address(THR, Thread::top_resource_offset())); 735 __ movl(EDX, Address(THR, Thread::top_resource_offset()));
721 __ pushl(EDX); 736 __ pushl(EDX);
722 __ movl(Address(THR, Thread::top_resource_offset()), Immediate(0)); 737 __ movl(Address(THR, Thread::top_resource_offset()), Immediate(0));
723 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the 738 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the
724 // code below. 739 // code below.
725 ASSERT(kExitLinkSlotFromEntryFp == -6); 740 ASSERT(kExitLinkSlotFromEntryFp == -7);
726 __ movl(EDX, Address(THR, Thread::top_exit_frame_info_offset())); 741 __ movl(EDX, Address(THR, Thread::top_exit_frame_info_offset()));
727 __ pushl(EDX); 742 __ pushl(EDX);
728 __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0)); 743 __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
729 744
730 // Load arguments descriptor array into EDX. 745 // Load arguments descriptor array into EDX.
731 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); 746 __ movl(EDX, Address(EBP, kArgumentsDescOffset));
732 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); 747 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle));
733 748
734 // Load number of arguments into EBX. 749 // Load number of arguments into EBX.
735 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 750 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
(...skipping 13 matching lines...) Expand all
749 764
750 __ Bind(&push_arguments); 765 __ Bind(&push_arguments);
751 __ movl(ECX, Address(EDI, EAX, TIMES_4, 0)); 766 __ movl(ECX, Address(EDI, EAX, TIMES_4, 0));
752 __ pushl(ECX); 767 __ pushl(ECX);
753 __ incl(EAX); 768 __ incl(EAX);
754 __ cmpl(EAX, EBX); 769 __ cmpl(EAX, EBX);
755 __ j(LESS, &push_arguments, Assembler::kNearJump); 770 __ j(LESS, &push_arguments, Assembler::kNearJump);
756 __ Bind(&done_push_arguments); 771 __ Bind(&done_push_arguments);
757 772
758 // Call the dart code entrypoint. 773 // Call the dart code entrypoint.
759 __ call(Address(EBP, kEntryPointOffset)); 774 __ movl(EAX, Address(EBP, kTargetCodeOffset));
775 __ movl(EAX, Address(EAX, VMHandles::kOffsetOfRawPtrInHandle));
776 __ call(FieldAddress(EAX, Code::entry_point_offset()));
760 777
761 // Reread the arguments descriptor array to obtain the number of passed 778 // Reread the arguments descriptor array to obtain the number of passed
762 // arguments. 779 // arguments.
763 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); 780 __ movl(EDX, Address(EBP, kArgumentsDescOffset));
764 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); 781 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle));
765 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 782 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
766 // Get rid of arguments pushed on the stack. 783 // Get rid of arguments pushed on the stack.
767 __ leal(ESP, Address(ESP, EDX, TIMES_2, 0)); // EDX is a Smi. 784 __ leal(ESP, Address(ESP, EDX, TIMES_2, 0)); // EDX is a Smi.
768 785
769 // Restore the saved top exit frame info and top resource back into the 786 // Restore the saved top exit frame info and top resource back into the
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 1011
995 1012
996 // Called for inline allocation of objects. 1013 // Called for inline allocation of objects.
997 // Input parameters: 1014 // Input parameters:
998 // ESP + 4 : type arguments object (only if class is parameterized). 1015 // ESP + 4 : type arguments object (only if class is parameterized).
999 // ESP : points to return address. 1016 // ESP : points to return address.
1000 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers. 1017 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers.
1001 // Returns patch_code_pc offset where patching code for disabling the stub 1018 // Returns patch_code_pc offset where patching code for disabling the stub
1002 // has been generated (similar to regularly generated Dart code). 1019 // has been generated (similar to regularly generated Dart code).
1003 void StubCode::GenerateAllocationStubForClass( 1020 void StubCode::GenerateAllocationStubForClass(
1004 Assembler* assembler, const Class& cls, 1021 Assembler* assembler, const Class& cls) {
1005 uword* entry_patch_offset, uword* patch_code_pc_offset) {
1006 *entry_patch_offset = assembler->CodeSize();
1007 const intptr_t kObjectTypeArgumentsOffset = 1 * kWordSize; 1022 const intptr_t kObjectTypeArgumentsOffset = 1 * kWordSize;
1008 const Immediate& raw_null = 1023 const Immediate& raw_null =
1009 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1024 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1010 // The generated code is different if the class is parameterized. 1025 // The generated code is different if the class is parameterized.
1011 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; 1026 const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
1012 ASSERT(!is_cls_parameterized || 1027 ASSERT(!is_cls_parameterized ||
1013 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); 1028 (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
1014 // kInlineInstanceSize is a constant used as a threshold for determining 1029 // kInlineInstanceSize is a constant used as a threshold for determining
1015 // when the object initialization should be done as a loop or as 1030 // when the object initialization should be done as a loop or as
1016 // straight line code. 1031 // straight line code.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 __ pushl(raw_null); // Push null type arguments. 1133 __ pushl(raw_null); // Push null type arguments.
1119 } 1134 }
1120 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. 1135 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object.
1121 __ popl(EAX); // Pop argument (type arguments of object). 1136 __ popl(EAX); // Pop argument (type arguments of object).
1122 __ popl(EAX); // Pop argument (class of object). 1137 __ popl(EAX); // Pop argument (class of object).
1123 __ popl(EAX); // Pop result (newly allocated object). 1138 __ popl(EAX); // Pop result (newly allocated object).
1124 // EAX: new object 1139 // EAX: new object
1125 // Restore the frame pointer. 1140 // Restore the frame pointer.
1126 __ LeaveFrame(); 1141 __ LeaveFrame();
1127 __ ret(); 1142 __ ret();
1128 // Emit function patching code. This will be swapped with the first 5 bytes
1129 // at entry point.
1130 *patch_code_pc_offset = assembler->CodeSize();
1131 __ Jmp(*StubCode::FixAllocationStubTarget_entry());
1132 } 1143 }
1133 1144
1134 1145
1135 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function 1146 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function
1136 // from the entry code of a dart function after an error in passed argument 1147 // from the entry code of a dart function after an error in passed argument
1137 // name or number is detected. 1148 // name or number is detected.
1138 // Input parameters: 1149 // Input parameters:
1139 // ESP : points to return address. 1150 // ESP : points to return address.
1140 // ESP + 4 : address of last argument. 1151 // ESP + 4 : address of last argument.
1141 // EDX : arguments descriptor array. 1152 // EDX : arguments descriptor array.
(...skipping 19 matching lines...) Expand all
1161 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); 1172 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
1162 // noSuchMethod on closures always throws an error, so it will never return. 1173 // noSuchMethod on closures always throws an error, so it will never return.
1163 __ int3(); 1174 __ int3();
1164 } 1175 }
1165 1176
1166 1177
1167 // Cannot use function object from ICData as it may be the inlined 1178 // Cannot use function object from ICData as it may be the inlined
1168 // function and not the top-scope function. 1179 // function and not the top-scope function.
1169 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1180 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1170 Register ic_reg = ECX; 1181 Register ic_reg = ECX;
1171 Register func_reg = EDI; 1182 Register func_reg = EBX;
1172 if (FLAG_trace_optimized_ic_calls) { 1183 if (FLAG_trace_optimized_ic_calls) {
1173 __ EnterStubFrame(); 1184 __ EnterStubFrame();
1174 __ pushl(func_reg); // Preserve 1185 __ pushl(func_reg); // Preserve
1175 __ pushl(ic_reg); // Preserve. 1186 __ pushl(ic_reg); // Preserve.
1176 __ pushl(ic_reg); // Argument. 1187 __ pushl(ic_reg); // Argument.
1177 __ pushl(func_reg); // Argument. 1188 __ pushl(func_reg); // Argument.
1178 __ CallRuntime(kTraceICCallRuntimeEntry, 2); 1189 __ CallRuntime(kTraceICCallRuntimeEntry, 2);
1179 __ popl(EAX); // Discard argument; 1190 __ popl(EAX); // Discard argument;
1180 __ popl(EAX); // Discard argument; 1191 __ popl(EAX); // Discard argument;
1181 __ popl(ic_reg); // Restore. 1192 __ popl(ic_reg); // Restore.
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { 1708 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
1698 __ EnterStubFrame(); 1709 __ EnterStubFrame();
1699 // Save IC data. 1710 // Save IC data.
1700 __ pushl(ECX); 1711 __ pushl(ECX);
1701 // Room for result. Debugger stub returns address of the 1712 // Room for result. Debugger stub returns address of the
1702 // unpatched runtime stub. 1713 // unpatched runtime stub.
1703 const Immediate& raw_null = 1714 const Immediate& raw_null =
1704 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1715 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1705 __ pushl(raw_null); // Room for result. 1716 __ pushl(raw_null); // Room for result.
1706 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); 1717 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
1707 __ popl(EAX); // Address of original stub. 1718 __ popl(EAX); // Code of original stub.
1708 __ popl(ECX); // Restore IC data. 1719 __ popl(ECX); // Restore IC data.
1709 __ LeaveFrame(); 1720 __ LeaveFrame();
1710 __ jmp(EAX); // Jump to original stub. 1721 // Jump to original stub.
1722 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
1723 __ jmp(EAX);
1711 } 1724 }
1712 1725
1713 1726
1714 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { 1727 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
1715 __ EnterStubFrame(); 1728 __ EnterStubFrame();
1716 // Room for result. Debugger stub returns address of the 1729 // Room for result. Debugger stub returns address of the
1717 // unpatched runtime stub. 1730 // unpatched runtime stub.
1718 const Immediate& raw_null = 1731 const Immediate& raw_null =
1719 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1732 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1720 __ pushl(raw_null); // Room for result. 1733 __ pushl(raw_null); // Room for result.
1721 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); 1734 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
1722 __ popl(EAX); // Address of original stub. 1735 __ popl(EAX); // Code of the original stub
1723 __ LeaveFrame(); 1736 __ LeaveFrame();
1724 __ jmp(EAX); // Jump to original stub. 1737 // Jump to original stub.
1738 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
1739 __ jmp(EAX);
1725 } 1740 }
1726 1741
1727 1742
1728 // Called only from unoptimized code. 1743 // Called only from unoptimized code.
1729 void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) { 1744 void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) {
1730 // Check single stepping. 1745 // Check single stepping.
1731 Label stepping, done_stepping; 1746 Label stepping, done_stepping;
1732 __ LoadIsolate(EAX); 1747 __ LoadIsolate(EAX);
1733 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); 1748 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset()));
1734 __ cmpl(EAX, Immediate(0)); 1749 __ cmpl(EAX, Immediate(0));
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 // Set tag. 1901 // Set tag.
1887 __ movl(Address(EDI, Isolate::vm_tag_offset()), 1902 __ movl(Address(EDI, Isolate::vm_tag_offset()),
1888 Immediate(VMTag::kDartTagId)); 1903 Immediate(VMTag::kDartTagId));
1889 // Clear top exit frame. 1904 // Clear top exit frame.
1890 __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0)); 1905 __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
1891 __ jmp(EBX); // Jump to the exception handler code. 1906 __ jmp(EBX); // Jump to the exception handler code.
1892 } 1907 }
1893 1908
1894 1909
1895 // Calls to the runtime to optimize the given function. 1910 // Calls to the runtime to optimize the given function.
1896 // EDI: function to be reoptimized. 1911 // EBX: function to be reoptimized.
1897 // EDX: argument descriptor (preserved). 1912 // EDX: argument descriptor (preserved).
1898 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { 1913 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
1899 const Immediate& raw_null = 1914 const Immediate& raw_null =
1900 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1915 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1901 __ EnterStubFrame(); 1916 __ EnterStubFrame();
1902 __ pushl(EDX); 1917 __ pushl(EDX);
1903 __ pushl(raw_null); // Setup space on stack for return value. 1918 __ pushl(raw_null); // Setup space on stack for return value.
1904 __ pushl(EDI); 1919 __ pushl(EBX);
1905 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); 1920 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
1906 __ popl(EAX); // Discard argument. 1921 __ popl(EAX); // Discard argument.
1907 __ popl(EAX); // Get Code object 1922 __ popl(EAX); // Get Code object
1908 __ popl(EDX); // Restore argument descriptor. 1923 __ popl(EDX); // Restore argument descriptor.
1909 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); 1924 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
1910 __ LeaveFrame(); 1925 __ LeaveFrame();
1911 __ jmp(EAX); 1926 __ jmp(EAX);
1912 __ int3(); 1927 __ int3();
1913 } 1928 }
1914 1929
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2061 // Call the target found in the cache. For a class id match, this is a 2076 // Call the target found in the cache. For a class id match, this is a
2062 // proper target for the given name and arguments descriptor. If the 2077 // proper target for the given name and arguments descriptor. If the
2063 // illegal class id was found, the target is a cache miss handler that can 2078 // illegal class id was found, the target is a cache miss handler that can
2064 // be invoked as a normal Dart function. 2079 // be invoked as a normal Dart function.
2065 __ movl(EAX, FieldAddress(EDI, ECX, TIMES_4, base + kWordSize)); 2080 __ movl(EAX, FieldAddress(EDI, ECX, TIMES_4, base + kWordSize));
2066 __ movl(target, FieldAddress(EAX, Function::entry_point_offset())); 2081 __ movl(target, FieldAddress(EAX, Function::entry_point_offset()));
2067 } 2082 }
2068 2083
2069 2084
2070 // Called from megamorphic calls. 2085 // Called from megamorphic calls.
2071 // EDI: receiver. 2086 // ECX: receiver.
2072 // EBX: lookup cache. 2087 // EBX: lookup cache.
2073 // Result: 2088 // Result:
2074 // EBX: entry point. 2089 // EBX: entry point.
2075 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 2090 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
2076 EmitMegamorphicLookup(assembler, EDI, EBX, EBX); 2091 EmitMegamorphicLookup(assembler, ECX, EBX, EBX);
2077 __ ret(); 2092 __ ret();
2078 } 2093 }
2079 2094
2080 2095
2081 } // namespace dart 2096 } // namespace dart
2082 2097
2083 #endif // defined TARGET_ARCH_IA32 2098 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_arm64.cc ('k') | runtime/vm/stub_code_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698