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

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

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