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

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