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

Side by Side Diff: vm/stub_code_ia32.cc

Issue 10375059: Use a reserved stack local variable to store the Code object so that it can be looked up easily whe… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « vm/stack_frame.cc ('k') | vm/stub_code_x64.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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"
9 #include "vm/assembler_macros.h"
8 #include "vm/code_generator.h" 10 #include "vm/code_generator.h"
9 #include "vm/compiler.h" 11 #include "vm/compiler.h"
10 #include "vm/object_store.h" 12 #include "vm/object_store.h"
11 #include "vm/pages.h" 13 #include "vm/pages.h"
12 #include "vm/resolver.h" 14 #include "vm/resolver.h"
13 #include "vm/scavenger.h" 15 #include "vm/scavenger.h"
14 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
15 17
16 18
17 #define __ assembler-> 19 #define __ assembler->
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 96
95 // Input parameters: 97 // Input parameters:
96 // ESP : points to return address. 98 // ESP : points to return address.
97 // EAX : stop message (const char*). 99 // EAX : stop message (const char*).
98 // Must preserve all registers, except EAX. 100 // Must preserve all registers, except EAX.
99 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { 101 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
100 // Preserve caller-saved registers. 102 // Preserve caller-saved registers.
101 __ pushl(ECX); 103 __ pushl(ECX);
102 __ pushl(EDX); 104 __ pushl(EDX);
103 105
104 __ EnterFrame(0); 106 // Create a stub frame as we are pushing some objects on the stack before
107 // calling into the runtime.
108 AssemblerMacros::EnterStubFrame(assembler);
105 109
106 // Reserve space for the native argument and align frame before entering 110 // Reserve space for the native argument and align frame before entering
107 // the C++ world. 111 // the C++ world.
108 __ AddImmediate(ESP, Immediate(-sizeof(kWordSize))); 112 __ AddImmediate(ESP, Immediate(-sizeof(kWordSize)));
109 if (OS::ActivationFrameAlignment() > 0) { 113 if (OS::ActivationFrameAlignment() > 0) {
110 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 114 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
111 } 115 }
112 116
113 // Pass argument and call native function. 117 // Pass argument and call native function.
114 __ movl(Address(ESP, 0), EAX); 118 __ movl(Address(ESP, 0), EAX);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 const Immediate raw_null = 208 const Immediate raw_null =
205 Immediate(reinterpret_cast<intptr_t>(Object::null())); 209 Immediate(reinterpret_cast<intptr_t>(Object::null()));
206 210
207 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); 211 __ movl(EAX, FieldAddress(ECX, Function::code_offset()));
208 __ cmpl(EAX, raw_null); 212 __ cmpl(EAX, raw_null);
209 Label function_compiled; 213 Label function_compiled;
210 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); 214 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump);
211 215
212 // Create a stub frame as we are pushing some objects on the stack before 216 // Create a stub frame as we are pushing some objects on the stack before
213 // calling into the runtime. 217 // calling into the runtime.
214 __ EnterFrame(0); 218 AssemblerMacros::EnterStubFrame(assembler);
215 219
216 __ pushl(EDX); // Preserve arguments descriptor array. 220 __ pushl(EDX); // Preserve arguments descriptor array.
217 __ pushl(ECX); 221 __ pushl(ECX);
218 __ CallRuntime(kCompileFunctionRuntimeEntry); 222 __ CallRuntime(kCompileFunctionRuntimeEntry);
219 __ popl(ECX); // Restore read-only function object argument in ECX. 223 __ popl(ECX); // Restore read-only function object argument in ECX.
220 __ popl(EDX); // Restore arguments descriptor array. 224 __ popl(EDX); // Restore arguments descriptor array.
221 // Restore EAX. 225 // Restore EAX.
222 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); 226 __ movl(EAX, FieldAddress(ECX, Function::code_offset()));
223 227
224 // Remove the stub frame as we are about to jump to the dart function. 228 // Remove the stub frame as we are about to jump to the dart function.
225 __ LeaveFrame(); 229 __ LeaveFrame();
226 230
227 __ Bind(&function_compiled); 231 __ Bind(&function_compiled);
228 // Patch caller. 232 // Patch caller.
229 __ EnterFrame(0); 233
234 // Create a stub frame as we are pushing some objects on the stack before
235 // calling into the runtime.
236 AssemblerMacros::EnterStubFrame(assembler);
230 237
231 __ pushl(EDX); // Preserve arguments descriptor array. 238 __ pushl(EDX); // Preserve arguments descriptor array.
232 __ pushl(ECX); // Preserve function object. 239 __ pushl(ECX); // Preserve function object.
233 __ CallRuntime(kPatchStaticCallRuntimeEntry); 240 __ CallRuntime(kPatchStaticCallRuntimeEntry);
234 __ popl(ECX); // Restore function object argument in ECX. 241 __ popl(ECX); // Restore function object argument in ECX.
235 __ popl(EDX); // Restore arguments descriptor array. 242 __ popl(EDX); // Restore arguments descriptor array.
236 // Remove the stub frame as we are about to jump to the dart function. 243 // Remove the stub frame as we are about to jump to the dart function.
237 __ LeaveFrame(); 244 __ LeaveFrame();
245
238 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); 246 __ movl(EAX, FieldAddress(ECX, Function::code_offset()));
239
240 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); 247 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset()));
241 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 248 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
242 __ jmp(ECX); 249 __ jmp(ECX);
243 } 250 }
244 251
245 252
246 // Called from a static call only when an invalid code has been entered 253 // Called from a static call only when an invalid code has been entered
247 // (invalid because its function was optimized or deoptimized). 254 // (invalid because its function was optimized or deoptimized).
248 // ECX: function object. 255 // ECX: function object.
249 // EDX: arguments descriptor array (num_args is first Smi element). 256 // EDX: arguments descriptor array (num_args is first Smi element).
250 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { 257 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
251 __ EnterFrame(0); 258 // Create a stub frame as we are pushing some objects on the stack before
259 // calling into the runtime.
260 AssemblerMacros::EnterStubFrame(assembler);
252 __ pushl(EDX); // Preserve arguments descriptor array. 261 __ pushl(EDX); // Preserve arguments descriptor array.
253 __ pushl(ECX); // Preserve target function. 262 __ pushl(ECX); // Preserve target function.
254 __ pushl(ECX); // Target function. 263 __ pushl(ECX); // Target function.
255 __ CallRuntime(kFixCallersTargetRuntimeEntry); 264 __ CallRuntime(kFixCallersTargetRuntimeEntry);
256 __ popl(EAX); // discard argument. 265 __ popl(EAX); // discard argument.
257 __ popl(EAX); // Restore function. 266 __ popl(EAX); // Restore function.
258 __ popl(EDX); // Restore arguments descriptor array. 267 __ popl(EDX); // Restore arguments descriptor array.
259 __ movl(EAX, FieldAddress(EAX, Function::code_offset())); 268 __ movl(EAX, FieldAddress(EAX, Function::code_offset()));
260 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); 269 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
261 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 270 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 397 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
389 const Immediate raw_null = 398 const Immediate raw_null =
390 Immediate(reinterpret_cast<intptr_t>(Object::null())); 399 Immediate(reinterpret_cast<intptr_t>(Object::null()));
391 400
392 MegamorphicLookup(assembler); 401 MegamorphicLookup(assembler);
393 // Lookup in function_table_ failed, resolve, compile and enter function 402 // Lookup in function_table_ failed, resolve, compile and enter function
394 // into function_table_. 403 // into function_table_.
395 404
396 // Create a stub frame as we are pushing some objects on the stack before 405 // Create a stub frame as we are pushing some objects on the stack before
397 // calling into the runtime. 406 // calling into the runtime.
398 __ EnterFrame(0); 407 AssemblerMacros::EnterStubFrame(assembler);
399 408
400 // Preserve values across call to resolving. 409 // Preserve values across call to resolving.
401 // Stack at this point: 410 // Stack at this point:
402 // TOS + 0: Saved EBP of previous frame. <== EBP 411 // TOS + 0: PC marker => RawInstruction object.
403 // TOS + 1: Dart code return address 412 // TOS + 1: Saved EBP of previous frame. <== EBP
404 // TOS + 2: Last argument of caller. 413 // TOS + 2: Dart code return address
414 // TOS + 3: Last argument of caller.
405 // .... 415 // ....
406 // Total number of args is the first Smi in args descriptor array (EDX). 416 // Total number of args is the first Smi in args descriptor array (EDX).
407 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 417 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
408 __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize)); // Get receiver. 418 __ movl(EAX, Address(EBP, EAX, TIMES_2, kWordSize)); // Get receiver.
409 __ pushl(EDX); // Preserve arguments descriptor array. 419 __ pushl(EDX); // Preserve arguments descriptor array.
410 __ pushl(EAX); // Preserve receiver. 420 __ pushl(EAX); // Preserve receiver.
411 __ pushl(ECX); // Preserve ic-data. 421 __ pushl(ECX); // Preserve ic-data.
412 // First resolve the function to get the function object. 422 // First resolve the function to get the function object.
413 423
414 __ pushl(raw_null); // Setup space on stack for return value. 424 __ pushl(raw_null); // Setup space on stack for return value.
415 __ pushl(EAX); // Push receiver. 425 __ pushl(EAX); // Push receiver.
416 __ CallRuntime(kResolveCompileInstanceFunctionRuntimeEntry); 426 __ CallRuntime(kResolveCompileInstanceFunctionRuntimeEntry);
417 __ popl(EAX); // Remove receiver pushed earlier. 427 __ popl(EAX); // Remove receiver pushed earlier.
418 __ popl(ECX); // Pop returned code object into ECX. 428 __ popl(ECX); // Pop returned code object into ECX.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 __ j(EQUAL, &function_not_found, Assembler::kNearJump); 509 __ j(EQUAL, &function_not_found, Assembler::kNearJump);
500 510
501 // ECX: Closure object. 511 // ECX: Closure object.
502 // EDI: Arguments descriptor array. 512 // EDI: Arguments descriptor array.
503 __ pushl(raw_null); // Setup space on stack for result from invoking Closure. 513 __ pushl(raw_null); // Setup space on stack for result from invoking Closure.
504 __ pushl(ECX); // Closure object. 514 __ pushl(ECX); // Closure object.
505 __ pushl(EDI); // Arguments descriptor. 515 __ pushl(EDI); // Arguments descriptor.
506 __ movl(EDI, FieldAddress(EDI, Array::data_offset())); 516 __ movl(EDI, FieldAddress(EDI, Array::data_offset()));
507 __ SmiUntag(EDI); 517 __ SmiUntag(EDI);
508 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. 518 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver.
509 PushArgumentsArray(assembler, (kWordSize * 5)); 519 PushArgumentsArray(assembler, (kWordSize * 6));
510 // Stack layout explaining "(kWordSize * 5)" offset. 520 // Stack layout explaining "(kWordSize * 6)" offset.
511 // TOS + 0: Argument array. 521 // TOS + 0: Argument array.
512 // TOS + 1: Arguments descriptor array. 522 // TOS + 1: Arguments descriptor array.
513 // TOS + 2: Closure object. 523 // TOS + 2: Closure object.
514 // TOS + 3: Place for result from closure function. 524 // TOS + 3: Place for result from closure function.
515 // TOS + 4: Saved EBP of previous frame. <== EBP 525 // TOS + 4: PC marker => RawInstruction object.
516 // TOS + 5: Dart code return address 526 // TOS + 5: Saved EBP of previous frame. <== EBP
517 // TOS + 6: Last argument of caller. 527 // TOS + 6: Dart code return address
528 // TOS + 7: Last argument of caller.
518 // .... 529 // ....
519 530
520 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); 531 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry);
521 // Remove arguments. 532 // Remove arguments.
522 __ popl(EAX); 533 __ popl(EAX);
523 __ popl(EAX); 534 __ popl(EAX);
524 __ popl(EAX); 535 __ popl(EAX);
525 __ popl(EAX); // Get result into EAX. 536 __ popl(EAX); // Get result into EAX.
526 537
527 // Remove the stub frame as we are about to return. 538 // Remove the stub frame as we are about to return.
528 __ LeaveFrame(); 539 __ LeaveFrame();
529 __ ret(); 540 __ ret();
530 541
531 __ Bind(&function_not_found); 542 __ Bind(&function_not_found);
532 // The target function was not found, so invoke method 543 // The target function was not found, so invoke method
533 // "void noSuchMethod(function_name, args_array)". 544 // "void noSuchMethod(function_name, args_array)".
534 // EAX: receiver. 545 // EAX: receiver.
535 // EDX: ic-data. 546 // EDX: ic-data.
536 // ECX: raw_null. 547 // ECX: raw_null.
537 // EDI: argument descriptor array. 548 // EDI: argument descriptor array.
538 549
539 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. 550 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod.
540 __ pushl(EAX); // Receiver. 551 __ pushl(EAX); // Receiver.
541 __ pushl(EDX); // IC-data. 552 __ pushl(EDX); // IC-data.
542 __ pushl(EDI); // Argument descriptor array. 553 __ pushl(EDI); // Argument descriptor array.
543 __ movl(EDI, FieldAddress(EDI, Array::data_offset())); 554 __ movl(EDI, FieldAddress(EDI, Array::data_offset()));
544 __ SmiUntag(EDI); 555 __ SmiUntag(EDI);
545 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. 556 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver.
546 // See stack layout below explaining "wordSize * 6" offset. 557 // See stack layout below explaining "wordSize * 7" offset.
547 PushArgumentsArray(assembler, (kWordSize * 6)); 558 PushArgumentsArray(assembler, (kWordSize * 7));
548 559
549 // Stack: 560 // Stack:
550 // TOS + 0: Argument array. 561 // TOS + 0: Argument array.
551 // TOS + 1: Argument descriptor array. 562 // TOS + 1: Argument descriptor array.
552 // TOS + 2: IC-data. 563 // TOS + 2: IC-data.
553 // TOS + 3: Receiver. 564 // TOS + 3: Receiver
554 // TOS + 4: Place for result from noSuchMethod. 565 // TOS + 4: Place for result from noSuchMethod.
555 // TOS + 5: Saved EBP of previous frame. <== EBP 566 // TOS + 5: PC marker => RawInstruction object.
556 // TOS + 6: Dart code return address 567 // TOS + 6: Saved EBP of previous frame. <== EBP
557 // TOS + 7: Last argument of caller. 568 // TOS + 7: Dart code return address
569 // TOS + 8: Last argument of caller.
558 // .... 570 // ....
559 571
560 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); 572 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry);
561 // Remove arguments. 573 // Remove arguments.
562 __ popl(EAX); 574 __ popl(EAX);
563 __ popl(EAX); 575 __ popl(EAX);
564 __ popl(EAX); 576 __ popl(EAX);
565 __ popl(EAX); 577 __ popl(EAX);
566 __ popl(EAX); // Get result into EAX. 578 __ popl(EAX); // Get result into EAX.
567 579
568 // Remove the stub frame as we are about to return. 580 // Remove the stub frame as we are about to return.
569 __ LeaveFrame(); 581 __ LeaveFrame();
570 __ ret(); 582 __ ret();
571 } 583 }
572 584
573 585
574 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 586 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
575 __ EnterFrame(0); 587 // Create a stub frame as we are pushing some objects on the stack before
588 // calling into the runtime.
589 AssemblerMacros::EnterStubFrame(assembler);
576 // EAX: deoptimization reason id. 590 // EAX: deoptimization reason id.
577 // Stack at this point: 591 // Stack at this point:
578 // TOS + 0: Saved EBP of function frame that will be deoptimized. <== EBP 592 // TOS + 0: PC marker => RawInstruction object.
579 // TOS + 1: Deoptimization point (return address), will be patched. 593 // TOS + 1: Saved EBP of function frame that will be deoptimized. <== EBP
580 // TOS + 2: top-of-stack at deoptimization point (all arguments on stack). 594 // TOS + 2: Deoptimization point (return address), will be patched.
595 // TOS + 3: top-of-stack at deoptimization point (all arguments on stack).
581 __ pushl(EAX); 596 __ pushl(EAX);
582 __ CallRuntime(kDeoptimizeRuntimeEntry); 597 __ CallRuntime(kDeoptimizeRuntimeEntry);
583 __ popl(EAX); 598 __ popl(EAX);
584 __ LeaveFrame(); 599 __ LeaveFrame();
585 __ ret(); 600 __ ret();
586 } 601 }
587 602
588 603
589 // Called for inline allocation of arrays. 604 // Called for inline allocation of arrays.
590 // Input parameters: 605 // Input parameters:
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 725
711 // Done allocating and initializing the array. 726 // Done allocating and initializing the array.
712 // EAX: new object. 727 // EAX: new object.
713 // EDX: Array length as Smi (preserved for the caller.) 728 // EDX: Array length as Smi (preserved for the caller.)
714 __ ret(); 729 __ ret();
715 } 730 }
716 731
717 // Unable to allocate the array using the fast inline code, just call 732 // Unable to allocate the array using the fast inline code, just call
718 // into the runtime. 733 // into the runtime.
719 __ Bind(&slow_case); 734 __ Bind(&slow_case);
720 __ EnterFrame(0); 735 // Create a stub frame as we are pushing some objects on the stack before
736 // calling into the runtime.
737 AssemblerMacros::EnterStubFrame(assembler);
721 __ pushl(raw_null); // Setup space on stack for return value. 738 __ pushl(raw_null); // Setup space on stack for return value.
722 __ pushl(EDX); // Array length as Smi. 739 __ pushl(EDX); // Array length as Smi.
723 __ pushl(ECX); // Element type. 740 __ pushl(ECX); // Element type.
724 __ CallRuntime(kAllocateArrayRuntimeEntry); 741 __ CallRuntime(kAllocateArrayRuntimeEntry);
725 __ popl(EAX); // Pop element type argument. 742 __ popl(EAX); // Pop element type argument.
726 __ popl(EDX); // Pop array length argument. 743 __ popl(EDX); // Pop array length argument.
727 __ popl(EAX); // Pop return value from return slot. 744 __ popl(EAX); // Pop return value from return slot.
728 __ LeaveFrame(); 745 __ LeaveFrame();
729 __ ret(); 746 __ ret();
730 } 747 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 __ movl(CTX, FieldAddress(EDI, Closure::context_offset())); 785 __ movl(CTX, FieldAddress(EDI, Closure::context_offset()));
769 786
770 // Load closure function code in EAX. 787 // Load closure function code in EAX.
771 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); 788 __ movl(EAX, FieldAddress(ECX, Function::code_offset()));
772 __ cmpl(EAX, raw_null); 789 __ cmpl(EAX, raw_null);
773 Label function_compiled; 790 Label function_compiled;
774 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); 791 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump);
775 792
776 // Create a stub frame as we are pushing some objects on the stack before 793 // Create a stub frame as we are pushing some objects on the stack before
777 // calling into the runtime. 794 // calling into the runtime.
778 __ EnterFrame(0); 795 AssemblerMacros::EnterStubFrame(assembler);
779 796
780 __ pushl(EDX); // Preserve arguments descriptor array. 797 __ pushl(EDX); // Preserve arguments descriptor array.
781 __ pushl(ECX); 798 __ pushl(ECX);
782 __ CallRuntime(kCompileFunctionRuntimeEntry); 799 __ CallRuntime(kCompileFunctionRuntimeEntry);
783 __ popl(ECX); // Restore read-only function object argument in ECX. 800 __ popl(ECX); // Restore read-only function object argument in ECX.
784 __ popl(EDX); // Restore arguments descriptor array. 801 __ popl(EDX); // Restore arguments descriptor array.
785 // Restore EAX. 802 // Restore EAX.
786 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); 803 __ movl(EAX, FieldAddress(ECX, Function::code_offset()));
787 804
788 // Remove the stub frame as we are about to jump to the closure function. 805 // Remove the stub frame as we are about to jump to the closure function.
(...skipping 10 matching lines...) Expand all
799 816
800 __ Bind(&not_closure); 817 __ Bind(&not_closure);
801 // Call runtime to report that a closure call was attempted on a non-closure 818 // Call runtime to report that a closure call was attempted on a non-closure
802 // object, passing the non-closure object and its arguments array. 819 // object, passing the non-closure object and its arguments array.
803 // EDI: non-closure object. 820 // EDI: non-closure object.
804 // EDX: arguments descriptor array (num_args is first Smi element, closure 821 // EDX: arguments descriptor array (num_args is first Smi element, closure
805 // object is not included in num_args). 822 // object is not included in num_args).
806 823
807 // Create a stub frame as we are pushing some objects on the stack before 824 // Create a stub frame as we are pushing some objects on the stack before
808 // calling into the runtime. 825 // calling into the runtime.
809 __ EnterFrame(0); 826 AssemblerMacros::EnterStubFrame(assembler);
810 827
811 __ pushl(raw_null); // Setup space on stack for result from error reporting. 828 __ pushl(raw_null); // Setup space on stack for result from error reporting.
812 __ pushl(EDI); // Non-closure object. 829 __ pushl(EDI); // Non-closure object.
813 // Total number of args is the first Smi in args descriptor array (EDX). 830 // Total number of args is the first Smi in args descriptor array (EDX).
814 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); // Load num_args. 831 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); // Load num_args.
815 __ SmiUntag(EDI); 832 __ SmiUntag(EDI);
816 // See stack layout below explaining "wordSize * 4" offset. 833 // See stack layout below explaining "wordSize * 5" offset.
817 PushArgumentsArray(assembler, (kWordSize * 4)); 834 PushArgumentsArray(assembler, (kWordSize * 5));
818 835
819 // Stack: 836 // Stack:
820 // TOS + 0: Argument array. 837 // TOS + 0: Argument array.
821 // TOS + 1: Non-closure object. 838 // TOS + 1: Non-closure object.
822 // TOS + 2: Place for result from reporting the error. 839 // TOS + 2: Place for result from reporting the error.
823 // TOS + 3: Saved EBP of previous frame. <== EBP 840 // TOS + 3: PC marker => RawInstruction object.
824 // TOS + 4: Dart code return address 841 // TOS + 4: Saved EBP of previous frame. <== EBP
825 // TOS + 5: Last argument of caller. 842 // TOS + 5: Dart code return address
843 // TOS + 6: Last argument of caller.
826 // .... 844 // ....
827 __ CallRuntime(kReportObjectNotClosureRuntimeEntry); 845 __ CallRuntime(kReportObjectNotClosureRuntimeEntry);
828 __ Stop("runtime call throws an exception"); 846 __ Stop("runtime call throws an exception");
829 } 847 }
830 848
831 849
832 // Called when invoking dart code from C++ (VM code). 850 // Called when invoking dart code from C++ (VM code).
833 // Input parameters: 851 // Input parameters:
834 // ESP : points to return address. 852 // ESP : points to return address.
835 // ESP + 4 : entrypoint of the dart function to call. 853 // ESP + 4 : entrypoint of the dart function to call.
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 __ cmpl(EDX, Immediate(0)); 1071 __ cmpl(EDX, Immediate(0));
1054 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1072 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1055 } 1073 }
1056 1074
1057 // Done allocating and initializing the context. 1075 // Done allocating and initializing the context.
1058 // EAX: new object. 1076 // EAX: new object.
1059 __ ret(); 1077 __ ret();
1060 1078
1061 __ Bind(&slow_case); 1079 __ Bind(&slow_case);
1062 } 1080 }
1063 // Create a stub frame. 1081 // Create a stub frame as we are pushing some objects on the stack before
1064 __ EnterFrame(0); 1082 // calling into the runtime.
1083 AssemblerMacros::EnterStubFrame(assembler);
1065 __ pushl(raw_null); // Setup space on stack for return value. 1084 __ pushl(raw_null); // Setup space on stack for return value.
1066 __ SmiTag(EDX); 1085 __ SmiTag(EDX);
1067 __ pushl(EDX); 1086 __ pushl(EDX);
1068 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. 1087 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context.
1069 __ popl(EAX); // Pop number of context variables argument. 1088 __ popl(EAX); // Pop number of context variables argument.
1070 __ popl(EAX); // Pop the new context object. 1089 __ popl(EAX); // Pop the new context object.
1071 // EAX: new object 1090 // EAX: new object
1072 // Restore the frame pointer. 1091 // Restore the frame pointer.
1073 __ LeaveFrame(); 1092 __ LeaveFrame();
1074 __ ret(); 1093 __ ret();
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 // EAX: new object. 1263 // EAX: new object.
1245 __ addl(EAX, Immediate(kHeapObjectTag)); 1264 __ addl(EAX, Immediate(kHeapObjectTag));
1246 __ ret(); 1265 __ ret();
1247 1266
1248 __ Bind(&slow_case); 1267 __ Bind(&slow_case);
1249 } 1268 }
1250 if (is_cls_parameterized) { 1269 if (is_cls_parameterized) {
1251 __ movl(EAX, Address(ESP, kObjectTypeArgumentsOffset)); 1270 __ movl(EAX, Address(ESP, kObjectTypeArgumentsOffset));
1252 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); 1271 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset));
1253 } 1272 }
1254 // Create a stub frame. 1273 // Create a stub frame as we are pushing some objects on the stack before
1255 __ EnterFrame(0); 1274 // calling into the runtime.
1275 AssemblerMacros::EnterStubFrame(assembler);
1256 __ pushl(raw_null); // Setup space on stack for return value. 1276 __ pushl(raw_null); // Setup space on stack for return value.
1257 __ PushObject(cls); // Push class of object to be allocated. 1277 __ PushObject(cls); // Push class of object to be allocated.
1258 if (is_cls_parameterized) { 1278 if (is_cls_parameterized) {
1259 __ pushl(EAX); // Push type arguments of object to be allocated. 1279 __ pushl(EAX); // Push type arguments of object to be allocated.
1260 __ pushl(EDX); // Push type arguments of instantiator. 1280 __ pushl(EDX); // Push type arguments of instantiator.
1261 } else { 1281 } else {
1262 __ pushl(raw_null); // Push null type arguments. 1282 __ pushl(raw_null); // Push null type arguments.
1263 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1283 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1264 } 1284 }
1265 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. 1285 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object.
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 __ ret(); 1421 __ ret();
1402 1422
1403 __ Bind(&slow_case); 1423 __ Bind(&slow_case);
1404 } 1424 }
1405 if (has_type_arguments) { 1425 if (has_type_arguments) {
1406 __ movl(ECX, Address(ESP, kTypeArgumentsOffset)); 1426 __ movl(ECX, Address(ESP, kTypeArgumentsOffset));
1407 } 1427 }
1408 if (is_implicit_instance_closure) { 1428 if (is_implicit_instance_closure) {
1409 __ movl(EAX, Address(ESP, kReceiverOffset)); 1429 __ movl(EAX, Address(ESP, kReceiverOffset));
1410 } 1430 }
1411 // Create a stub frame. 1431 // Create a stub frame as we are pushing some objects on the stack before
1412 __ EnterFrame(0); 1432 // calling into the runtime.
1433 AssemblerMacros::EnterStubFrame(assembler);
1413 __ pushl(raw_null); // Setup space on stack for return value. 1434 __ pushl(raw_null); // Setup space on stack for return value.
1414 __ PushObject(func); 1435 __ PushObject(func);
1415 if (is_implicit_static_closure) { 1436 if (is_implicit_static_closure) {
1416 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); 1437 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry);
1417 } else { 1438 } else {
1418 if (is_implicit_instance_closure) { 1439 if (is_implicit_instance_closure) {
1419 __ pushl(EAX); // Receiver. 1440 __ pushl(EAX); // Receiver.
1420 } 1441 }
1421 if (has_type_arguments) { 1442 if (has_type_arguments) {
1422 __ pushl(ECX); // Push type arguments of closure to be allocated. 1443 __ pushl(ECX); // Push type arguments of closure to be allocated.
(...skipping 15 matching lines...) Expand all
1438 // EAX: new object 1459 // EAX: new object
1439 // Restore the frame pointer. 1460 // Restore the frame pointer.
1440 __ LeaveFrame(); 1461 __ LeaveFrame();
1441 __ ret(); 1462 __ ret();
1442 } 1463 }
1443 1464
1444 1465
1445 // Called for invoking noSuchMethod function from the entry code of a dart 1466 // Called for invoking noSuchMethod function from the entry code of a dart
1446 // function after an error in passed named arguments is detected. 1467 // function after an error in passed named arguments is detected.
1447 // Input parameters: 1468 // Input parameters:
1469 // EBP - 4 : PC marker => RawInstruction object.
1448 // EBP : points to previous frame pointer. 1470 // EBP : points to previous frame pointer.
1449 // EBP + 4 : points to return address. 1471 // EBP + 4 : points to return address.
1450 // EBP + 8 : address of last argument (arg n-1). 1472 // EBP + 8 : address of last argument (arg n-1).
1451 // EBP + 8 + 4*(n-1) : address of first argument (arg 0). 1473 // EBP + 8 + 4*(n-1) : address of first argument (arg 0).
1452 // ECX : ic-data. 1474 // ECX : ic-data.
1453 // EDX : arguments descriptor array. 1475 // EDX : arguments descriptor array.
1454 // Uses EAX, EBX, EDI as temporary registers. 1476 // Uses EAX, EBX, EDI as temporary registers.
1455 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1477 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1456 // The target function was not found, so invoke method 1478 // The target function was not found, so invoke method
1457 // "void noSuchMethod(function_name, Array arguments)". 1479 // "void noSuchMethod(function_name, Array arguments)".
1458 // TODO(regis): For now, we simply pass the actual arguments, both positional 1480 // TODO(regis): For now, we simply pass the actual arguments, both positional
1459 // and named, as the argument array. This is not correct if out-of-order 1481 // and named, as the argument array. This is not correct if out-of-order
1460 // named arguments were passed. 1482 // named arguments were passed.
1461 // The signature of the "noSuchMethod" method has to change from 1483 // The signature of the "noSuchMethod" method has to change from
1462 // noSuchMethod(String name, Array arguments) to something like 1484 // noSuchMethod(String name, Array arguments) to something like
1463 // noSuchMethod(InvocationMirror call). 1485 // noSuchMethod(InvocationMirror call).
1464 // Also, the class NoSuchMethodException has to be modified accordingly. 1486 // Also, the class NoSuchMethodException has to be modified accordingly.
1465 // Total number of args is the first Smi in args descriptor array (EDX). 1487 // Total number of args is the first Smi in args descriptor array (EDX).
1466 const Immediate raw_null = 1488 const Immediate raw_null =
1467 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1489 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1468 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); 1490 __ movl(EDI, FieldAddress(EDX, Array::data_offset()));
1469 __ SmiUntag(EDI); 1491 __ SmiUntag(EDI);
1470 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver. 1492 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver.
1471 1493
1472 __ EnterFrame(0); 1494 // Create a stub frame as we are pushing some objects on the stack before
1495 // calling into the runtime.
1496 AssemblerMacros::EnterStubFrame(assembler);
1497
1473 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. 1498 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod.
1474 __ pushl(EAX); // Receiver. 1499 __ pushl(EAX); // Receiver.
1475 __ pushl(ECX); // IC data array. 1500 __ pushl(ECX); // IC data array.
1476 __ pushl(EDX); // Arguments descriptor array. 1501 __ pushl(EDX); // Arguments descriptor array.
1477 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. 1502 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver.
1478 // See stack layout below explaining "wordSize * 8" offset. 1503 // See stack layout below explaining "wordSize * 10" offset.
1479 PushArgumentsArray(assembler, (kWordSize * 8)); 1504 PushArgumentsArray(assembler, (kWordSize * 10));
1480 1505
1481 // Stack: 1506 // Stack:
1482 // TOS + 0: Argument array. 1507 // TOS + 0: Argument array.
1483 // TOS + 1: Arguments descriptor array. 1508 // TOS + 1: Arguments descriptor array.
1484 // TOS + 2: Ic-data. 1509 // TOS + 2: Ic-data.
1485 // TOS + 3: Receiver. 1510 // TOS + 3: Receiver.
1486 // TOS + 4: Place for result from noSuchMethod. 1511 // TOS + 4: Place for result from noSuchMethod.
1487 // TOS + 5: Saved EBP of previous frame. <== EBP 1512 // TOS + 5: PC marker => RawInstruction object.
1488 // TOS + 6: Dart callee (or stub) code return address 1513 // TOS + 6: Saved EBP of previous frame. <== EBP
1489 // TOS + 7: Saved EBP of dart caller frame. 1514 // TOS + 7: Dart callee (or stub) code return address
1490 // TOS + 8: Dart caller code return address 1515 // TOS + 8: PC marker => RawInstruction object of dart caller frame.
1491 // TOS + 9: Last argument of caller. 1516 // TOS + 9: Saved EBP of dart caller frame.
1517 // TOS + 10: Dart caller code return address
1518 // TOS + 11: Last argument of caller.
1492 // .... 1519 // ....
1493 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); 1520 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry);
1494 // Remove arguments. 1521 // Remove arguments.
1495 __ popl(EAX); 1522 __ popl(EAX);
1496 __ popl(EAX); 1523 __ popl(EAX);
1497 __ popl(EAX); 1524 __ popl(EAX);
1498 __ popl(EAX); 1525 __ popl(EAX);
1499 __ popl(EAX); // Get result into EAX. 1526 __ popl(EAX); // Get result into EAX.
1500 1527
1501 // Remove the stub frame as we are about to return. 1528 // Remove the stub frame as we are about to return.
1502 __ LeaveFrame(); 1529 __ LeaveFrame();
1503 __ ret(); 1530 __ ret();
1504 } 1531 }
1505 1532
1506 1533
1507 1534
1508 // Generate inline cache check for 'num_args'. 1535 // Generate inline cache check for 'num_args'.
1509 // ECX: Inline cache data object. 1536 // ECX: Inline cache data object.
1510 // EDX: Arguments descriptor array. 1537 // EDX: Arguments descriptor array.
1511 // TOS(0): return address 1538 // TOS(0): return address
1512 // Control flow: 1539 // Control flow:
1513 // - If receiver is null -> jump to IC miss. 1540 // - If receiver is null -> jump to IC miss.
1514 // - If receiver is Smi -> load Smi class. 1541 // - If receiver is Smi -> load Smi class.
1515 // - If receiver is not-Smi -> load receiver's class. 1542 // - If receiver is not-Smi -> load receiver's class.
1516 // - Check if 'num_args' (including receiver) match any IC data group. 1543 // - Check if 'num_args' (including receiver) match any IC data group.
1517 // - Match found -> jump to target. 1544 // - Match found -> jump to target.
1518 // - Match not found -> jump to IC miss. 1545 // - Match not found -> jump to IC miss.
1519 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1546 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1520 intptr_t num_args) { 1547 intptr_t num_args) {
1548 const Immediate raw_null =
1549 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1550
1521 __ movl(EBX, FieldAddress(ECX, ICData::function_offset())); 1551 __ movl(EBX, FieldAddress(ECX, ICData::function_offset()));
1522 __ incl(FieldAddress(EBX, Function::usage_counter_offset())); 1552 __ incl(FieldAddress(EBX, Function::usage_counter_offset()));
1523 if (CodeGenerator::CanOptimize()) { 1553 if (CodeGenerator::CanOptimize()) {
1524 __ cmpl(FieldAddress(EBX, Function::usage_counter_offset()), 1554 __ cmpl(FieldAddress(EBX, Function::usage_counter_offset()),
1525 Immediate(FLAG_optimization_counter_threshold)); 1555 Immediate(FLAG_optimization_counter_threshold));
1526 Label not_yet_hot; 1556 Label not_yet_hot;
1527 __ j(LESS_EQUAL, &not_yet_hot, Assembler::kNearJump); 1557 __ j(LESS_EQUAL, &not_yet_hot, Assembler::kNearJump);
1528 __ EnterFrame(0); 1558 // Create a stub frame as we are pushing some objects on the stack before
1559 // calling into the runtime.
1560 AssemblerMacros::EnterStubFrame(assembler);
1529 __ pushl(ECX); // Preserve inline cache data object. 1561 __ pushl(ECX); // Preserve inline cache data object.
1530 __ pushl(EDX); // Preserve arguments array. 1562 __ pushl(EDX); // Preserve arguments array.
1531 __ pushl(EBX); // Argument for runtime: function object. 1563 __ pushl(EBX); // Argument for runtime: function object.
1532 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); 1564 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
1533 __ popl(EBX); // Remove argument. 1565 __ popl(EBX); // Remove argument.
1534 __ popl(EDX); // Restore arguments array. 1566 __ popl(EDX); // Restore arguments array.
1535 __ popl(ECX); // Restore inline cache data object. 1567 __ popl(ECX); // Restore inline cache data object.
1536 __ LeaveFrame(); 1568 __ LeaveFrame();
1537 __ Bind(&not_yet_hot); 1569 __ Bind(&not_yet_hot);
1538 } 1570 }
(...skipping 21 matching lines...) Expand all
1560 } 1592 }
1561 #endif // DEBUG 1593 #endif // DEBUG
1562 1594
1563 // Loop that checks if there is an IC data match. 1595 // Loop that checks if there is an IC data match.
1564 // EAX: receiver's class. 1596 // EAX: receiver's class.
1565 // ECX: IC data object (preserved). 1597 // ECX: IC data object (preserved).
1566 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); 1598 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1567 // EBX: ic_data_array with check entries: classes and target functions. 1599 // EBX: ic_data_array with check entries: classes and target functions.
1568 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); 1600 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1569 // EBX: points directly to the first ic data array element. 1601 // EBX: points directly to the first ic data array element.
1570 const Immediate raw_null =
1571 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1572 Label loop, found; 1602 Label loop, found;
1573 if (num_args == 1) { 1603 if (num_args == 1) {
1574 __ Bind(&loop); 1604 __ Bind(&loop);
1575 __ movl(EDI, Address(EBX, 0)); // Get class to check. 1605 __ movl(EDI, Address(EBX, 0)); // Get class to check.
1576 __ cmpl(EAX, EDI); // Match? 1606 __ cmpl(EAX, EDI); // Match?
1577 __ j(EQUAL, &found, Assembler::kNearJump); 1607 __ j(EQUAL, &found, Assembler::kNearJump);
1578 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target). 1608 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target).
1579 __ cmpl(EDI, raw_null); // Done? 1609 __ cmpl(EDI, raw_null); // Done?
1580 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1610 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1581 } else if (num_args == 2) { 1611 } else if (num_args == 2) {
(...skipping 23 matching lines...) Expand all
1605 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. 1635 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element.
1606 __ cmpl(EDI, raw_null); // Done? 1636 __ cmpl(EDI, raw_null); // Done?
1607 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1637 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1608 } 1638 }
1609 1639
1610 __ Bind(&ic_miss); 1640 __ Bind(&ic_miss);
1611 // Compute address of arguments (first read number of arguments from argument 1641 // Compute address of arguments (first read number of arguments from argument
1612 // descriptor array and then compute address on the stack). 1642 // descriptor array and then compute address on the stack).
1613 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1643 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1614 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. 1644 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi.
1615 __ EnterFrame(0); 1645 // Create a stub frame as we are pushing some objects on the stack before
1646 // calling into the runtime.
1647 AssemblerMacros::EnterStubFrame(assembler);
1616 __ pushl(EDX); // Preserve arguments array. 1648 __ pushl(EDX); // Preserve arguments array.
1617 __ pushl(ECX); // Preserve IC data array 1649 __ pushl(ECX); // Preserve IC data array
1618 __ pushl(raw_null); // Setup space on stack for result (target code object). 1650 __ pushl(raw_null); // Setup space on stack for result (target code object).
1619 // Push call arguments. 1651 // Push call arguments.
1620 for (intptr_t i = 0; i < num_args; i++) { 1652 for (intptr_t i = 0; i < num_args; i++) {
1621 __ movl(EDX, Address(EAX, -kWordSize * i)); 1653 __ movl(EDX, Address(EAX, -kWordSize * i));
1622 __ pushl(EDX); 1654 __ pushl(EDX);
1623 } 1655 }
1624 if (num_args == 1) { 1656 if (num_args == 1) {
1625 __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry); 1657 __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 1718
1687 1719
1688 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1720 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1689 return GenerateNArgsCheckInlineCacheStub(assembler, 2); 1721 return GenerateNArgsCheckInlineCacheStub(assembler, 2);
1690 } 1722 }
1691 1723
1692 // ECX: Function object. 1724 // ECX: Function object.
1693 // EDX: Arguments array. 1725 // EDX: Arguments array.
1694 // TOS(0): return address (Dart code). 1726 // TOS(0): return address (Dart code).
1695 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1727 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1696 __ EnterFrame(0); 1728 // Create a stub frame as we are pushing some objects on the stack before
1729 // calling into the runtime.
1730 AssemblerMacros::EnterStubFrame(assembler);
1697 __ pushl(EDX); 1731 __ pushl(EDX);
1698 __ pushl(ECX); 1732 __ pushl(ECX);
1699 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); 1733 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
1700 __ popl(ECX); 1734 __ popl(ECX);
1701 __ popl(EDX); 1735 __ popl(EDX);
1702 __ LeaveFrame(); 1736 __ LeaveFrame();
1703 1737
1704 // Now call the static function. The breakpoint handler function 1738 // Now call the static function. The breakpoint handler function
1705 // ensures that the call target is compiled. 1739 // ensures that the call target is compiled.
1706 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); 1740 __ movl(EAX, FieldAddress(ECX, Function::code_offset()));
1707 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); 1741 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset()));
1708 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1742 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1709 __ jmp(ECX); 1743 __ jmp(ECX);
1710 } 1744 }
1711 1745
1712 1746
1713 // TOS(0): return address (Dart code). 1747 // TOS(0): return address (Dart code).
1714 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { 1748 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
1715 __ EnterFrame(0); 1749 // Create a stub frame as we are pushing some objects on the stack before
1750 // calling into the runtime.
1751 AssemblerMacros::EnterStubFrame(assembler);
1716 __ pushl(EAX); 1752 __ pushl(EAX);
1717 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); 1753 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry);
1718 __ popl(EAX); 1754 __ popl(EAX);
1719 __ LeaveFrame(); 1755 __ LeaveFrame();
1720 1756
1721 // Instead of returning to the patched Dart function, emulate the 1757 // Instead of returning to the patched Dart function, emulate the
1722 // smashed return code pattern and return to the function's caller. 1758 // smashed return code pattern and return to the function's caller.
1723 __ popl(ECX); // Discard return address to patched dart code. 1759 __ popl(ECX); // Discard return address to patched dart code.
1724 // Execute function epilog code that was smashed in the Dart code. 1760 // Execute function epilog code that was smashed in the Dart code.
1725 __ LeaveFrame(); 1761 __ LeaveFrame();
1726 __ ret(); 1762 __ ret();
1727 } 1763 }
1728 1764
1729 1765
1730 // ECX: Inline cache data array. 1766 // ECX: Inline cache data array.
1731 // EDX: Arguments array. 1767 // EDX: Arguments array.
1732 // TOS(0): return address (Dart code). 1768 // TOS(0): return address (Dart code).
1733 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1769 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1734 __ EnterFrame(0); 1770 // Create a stub frame as we are pushing some objects on the stack before
1771 // calling into the runtime.
1772 AssemblerMacros::EnterStubFrame(assembler);
1735 __ pushl(ECX); 1773 __ pushl(ECX);
1736 __ pushl(EDX); 1774 __ pushl(EDX);
1737 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); 1775 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
1738 __ popl(EDX); 1776 __ popl(EDX);
1739 __ popl(ECX); 1777 __ popl(ECX);
1740 __ LeaveFrame(); 1778 __ LeaveFrame();
1741 1779
1742 // Find out which dispatch stub to call. 1780 // Find out which dispatch stub to call.
1743 Label ic_cache_one_arg; 1781 Label ic_cache_one_arg;
1744 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); 1782 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1854 // TOS + 2: instance. 1892 // TOS + 2: instance.
1855 // TOS + 3: cache array. 1893 // TOS + 3: cache array.
1856 // Result in ECX: null -> not found, otherwise result (true or false). 1894 // Result in ECX: null -> not found, otherwise result (true or false).
1857 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { 1895 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) {
1858 GenerateSubtypeNTestCacheStub(assembler, 3); 1896 GenerateSubtypeNTestCacheStub(assembler, 3);
1859 } 1897 }
1860 1898
1861 } // namespace dart 1899 } // namespace dart
1862 1900
1863 #endif // defined TARGET_ARCH_IA32 1901 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « vm/stack_frame.cc ('k') | vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698