OLD | NEW |
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/ic_data.h" | 10 #include "vm/ic_data.h" |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 // TOS + 2: Last argument of caller. | 413 // TOS + 2: Last argument of caller. |
414 // .... | 414 // .... |
415 // Total number of args is the first Smi in args descriptor array (EDX). | 415 // Total number of args is the first Smi in args descriptor array (EDX). |
416 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 416 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
417 __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize)); // Get receiver. | 417 __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize)); // Get receiver. |
418 __ pushl(EDX); // Preserve arguments descriptor array. | 418 __ pushl(EDX); // Preserve arguments descriptor array. |
419 __ pushl(EAX); // Preserve receiver. | 419 __ pushl(EAX); // Preserve receiver. |
420 __ pushl(ECX); // Preserve ic-data array. | 420 __ pushl(ECX); // Preserve ic-data array. |
421 // First resolve the function to get the function object. | 421 // First resolve the function to get the function object. |
422 | 422 |
423 // Setup space for return value on stack by pushing smi 0. | 423 __ pushl(raw_null); // Setup space on stack for return value. |
424 __ pushl(Immediate(0)); | |
425 __ pushl(EAX); // Push receiver. | 424 __ pushl(EAX); // Push receiver. |
426 __ CallRuntimeFromStub(kResolveCompileInstanceFunctionRuntimeEntry); | 425 __ CallRuntimeFromStub(kResolveCompileInstanceFunctionRuntimeEntry); |
427 __ popl(EAX); // Remove receiver pushed earlier. | 426 __ popl(EAX); // Remove receiver pushed earlier. |
428 __ popl(ECX); // Pop returned code object into ECX. | 427 __ popl(ECX); // Pop returned code object into ECX. |
429 // Pop preserved values | 428 // Pop preserved values |
430 __ popl(EDX); // Restore ic-data array. | 429 __ popl(EDX); // Restore ic-data array. |
431 __ popl(EAX); // Restore receiver. | 430 __ popl(EAX); // Restore receiver. |
432 __ popl(EDI); // Restore arguments descriptor array. | 431 __ popl(EDI); // Restore arguments descriptor array. |
433 | 432 |
434 __ cmpl(ECX, raw_null); | 433 __ cmpl(ECX, raw_null); |
(...skipping 14 matching lines...) Expand all Loading... |
449 // ECX: raw_null. | 448 // ECX: raw_null. |
450 // EDI: arguments descriptor array. | 449 // EDI: arguments descriptor array. |
451 // The target function was not found. | 450 // The target function was not found. |
452 // First check to see if this is a getter function and we are | 451 // First check to see if this is a getter function and we are |
453 // trying to create a closure of an instance function. | 452 // trying to create a closure of an instance function. |
454 // Push values that need to be preserved across runtime call. | 453 // Push values that need to be preserved across runtime call. |
455 __ pushl(EAX); // Preserve receiver. | 454 __ pushl(EAX); // Preserve receiver. |
456 __ pushl(EDX); // Preserve ic-data array. | 455 __ pushl(EDX); // Preserve ic-data array. |
457 __ pushl(EDI); // Preserve arguments descriptor array. | 456 __ pushl(EDI); // Preserve arguments descriptor array. |
458 | 457 |
459 __ pushl(Immediate(0)); | 458 __ pushl(raw_null); // Setup space on stack for return value. |
460 __ pushl(EAX); // Push receiver. | 459 __ pushl(EAX); // Push receiver. |
461 __ pushl(EDX); // Ic-data array. | 460 __ pushl(EDX); // Ic-data array. |
462 __ CallRuntimeFromStub(kResolveImplicitClosureFunctionRuntimeEntry); | 461 __ CallRuntimeFromStub(kResolveImplicitClosureFunctionRuntimeEntry); |
463 __ popl(EAX); | 462 __ popl(EAX); |
464 __ popl(EAX); | 463 __ popl(EAX); |
465 __ popl(ECX); // Get return value into ECX, might be Closure object. | 464 __ popl(ECX); // Get return value into ECX, might be Closure object. |
466 | 465 |
467 // Pop preserved values. | 466 // Pop preserved values. |
468 __ popl(EDI); // Restore arguments descriptor array. | 467 __ popl(EDI); // Restore arguments descriptor array. |
469 __ popl(EDX); // Restore ic-data array. | 468 __ popl(EDX); // Restore ic-data array. |
(...skipping 14 matching lines...) Expand all Loading... |
484 // ECX: raw_null. | 483 // ECX: raw_null. |
485 // EDI: arguments descriptor array. | 484 // EDI: arguments descriptor array. |
486 // This is not the case of an instance so invoke the getter of the | 485 // This is not the case of an instance so invoke the getter of the |
487 // same name and see if we get a closure back which we are then | 486 // same name and see if we get a closure back which we are then |
488 // supposed to invoke. | 487 // supposed to invoke. |
489 // Push values that need to be preserved across runtime call. | 488 // Push values that need to be preserved across runtime call. |
490 __ pushl(EAX); // Preserve receiver. | 489 __ pushl(EAX); // Preserve receiver. |
491 __ pushl(EDX); // Preserve ic-data array. | 490 __ pushl(EDX); // Preserve ic-data array. |
492 __ pushl(EDI); // Preserve arguments descriptor array. | 491 __ pushl(EDI); // Preserve arguments descriptor array. |
493 | 492 |
494 __ pushl(Immediate(0)); | 493 __ pushl(raw_null); // Setup space on stack for return value. |
495 __ pushl(EAX); // Push receiver. | 494 __ pushl(EAX); // Push receiver. |
496 __ pushl(EDX); // Ic-data array. | 495 __ pushl(EDX); // Ic-data array. |
497 __ CallRuntimeFromStub(kResolveImplicitClosureThroughGetterRuntimeEntry); | 496 __ CallRuntimeFromStub(kResolveImplicitClosureThroughGetterRuntimeEntry); |
498 __ popl(EDX); // Pop argument. | 497 __ popl(EDX); // Pop argument. |
499 __ popl(EAX); // Pop argument. | 498 __ popl(EAX); // Pop argument. |
500 __ popl(ECX); // get return value into ECX, might be Closure object. | 499 __ popl(ECX); // get return value into ECX, might be Closure object. |
501 | 500 |
502 // Pop preserved values. | 501 // Pop preserved values. |
503 __ popl(EDI); // Restore arguments descriptor array. | 502 __ popl(EDI); // Restore arguments descriptor array. |
504 __ popl(EDX); // Restore ic-data array. | 503 __ popl(EDX); // Restore ic-data array. |
505 __ popl(EAX); // Restore receiver. | 504 __ popl(EAX); // Restore receiver. |
506 | 505 |
507 __ cmpl(ECX, raw_null); | 506 __ cmpl(ECX, raw_null); |
508 Label function_not_found; | 507 Label function_not_found; |
509 __ j(EQUAL, &function_not_found, Assembler::kNearJump); | 508 __ j(EQUAL, &function_not_found, Assembler::kNearJump); |
510 | 509 |
511 // ECX: Closure object. | 510 // ECX: Closure object. |
512 // EDI: Arguments descriptor array. | 511 // EDI: Arguments descriptor array. |
513 __ pushl(Immediate(0)); // Result from invoking Closure. | 512 __ pushl(raw_null); // Setup space on stack for result from invoking Closure. |
514 __ pushl(ECX); // Closure object. | 513 __ pushl(ECX); // Closure object. |
515 __ pushl(EDI); // Arguments descriptor. | 514 __ pushl(EDI); // Arguments descriptor. |
516 __ movl(EDI, FieldAddress(EDI, Array::data_offset())); | 515 __ movl(EDI, FieldAddress(EDI, Array::data_offset())); |
517 __ SmiUntag(EDI); | 516 __ SmiUntag(EDI); |
518 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. | 517 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. |
519 PushArgumentsArray(assembler, (kWordSize * 5)); | 518 PushArgumentsArray(assembler, (kWordSize * 5)); |
520 // Stack layout explaining "(kWordSize * 5)" offset. | 519 // Stack layout explaining "(kWordSize * 5)" offset. |
521 // TOS + 0: Argument array. | 520 // TOS + 0: Argument array. |
522 // TOS + 1: Arguments descriptor array. | 521 // TOS + 1: Arguments descriptor array. |
523 // TOS + 2: Closure object. | 522 // TOS + 2: Closure object. |
(...skipping 15 matching lines...) Expand all Loading... |
539 __ ret(); | 538 __ ret(); |
540 | 539 |
541 __ Bind(&function_not_found); | 540 __ Bind(&function_not_found); |
542 // The target function was not found, so invoke method | 541 // The target function was not found, so invoke method |
543 // "void noSuchMethod(function_name, args_array)". | 542 // "void noSuchMethod(function_name, args_array)". |
544 // EAX: receiver. | 543 // EAX: receiver. |
545 // EDX: ic-data array. | 544 // EDX: ic-data array. |
546 // ECX: raw_null. | 545 // ECX: raw_null. |
547 // EDI: argument descriptor array. | 546 // EDI: argument descriptor array. |
548 | 547 |
549 // Setup space for return value on stack by pushing smi 0. | 548 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. |
550 __ pushl(Immediate(0)); // Result from noSuchMethod. | |
551 __ pushl(EAX); // Receiver. | 549 __ pushl(EAX); // Receiver. |
552 __ pushl(EDX); // IC-data array. | 550 __ pushl(EDX); // IC-data array. |
553 __ pushl(EDI); // Argument descriptor array. | 551 __ pushl(EDI); // Argument descriptor array. |
554 __ movl(EDI, FieldAddress(EDI, Array::data_offset())); | 552 __ movl(EDI, FieldAddress(EDI, Array::data_offset())); |
555 __ SmiUntag(EDI); | 553 __ SmiUntag(EDI); |
556 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. | 554 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. |
557 // See stack layout below explaining "wordSize * 6" offset. | 555 // See stack layout below explaining "wordSize * 6" offset. |
558 PushArgumentsArray(assembler, (kWordSize * 6)); | 556 PushArgumentsArray(assembler, (kWordSize * 6)); |
559 | 557 |
560 // Stack: | 558 // Stack: |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 | 693 |
696 // Done allocating and initializing the array. | 694 // Done allocating and initializing the array. |
697 // EAX: new object. | 695 // EAX: new object. |
698 __ ret(); | 696 __ ret(); |
699 } | 697 } |
700 | 698 |
701 // Unable to allocate the array using the fast inline code, just call | 699 // Unable to allocate the array using the fast inline code, just call |
702 // into the runtime. | 700 // into the runtime. |
703 __ Bind(&slow_case); | 701 __ Bind(&slow_case); |
704 __ EnterFrame(0); | 702 __ EnterFrame(0); |
705 __ pushl(raw_null); // Push Null object for return value. | 703 __ pushl(raw_null); // Setup space on stack for return value. |
706 __ pushl(EDX); // Array length as Smi. | 704 __ pushl(EDX); // Array length as Smi. |
707 __ pushl(ECX); // Element type. | 705 __ pushl(ECX); // Element type. |
708 __ pushl(raw_null); // Null instantiator. | 706 __ pushl(raw_null); // Null instantiator. |
709 __ CallRuntimeFromStub(kAllocateArrayRuntimeEntry); | 707 __ CallRuntimeFromStub(kAllocateArrayRuntimeEntry); |
710 __ popl(EAX); // Pop instantiator. | 708 __ popl(EAX); // Pop instantiator. |
711 __ popl(EAX); // Pop element type argument. | 709 __ popl(EAX); // Pop element type argument. |
712 __ popl(EDX); // Pop array length argument. | 710 __ popl(EDX); // Pop array length argument. |
713 __ popl(EAX); // Pop return value from return slot. | 711 __ popl(EAX); // Pop return value from return slot. |
714 __ LeaveFrame(); | 712 __ LeaveFrame(); |
715 __ ret(); | 713 __ ret(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 // Call runtime to report that a closure call was attempted on a non-closure | 785 // Call runtime to report that a closure call was attempted on a non-closure |
788 // object, passing the non-closure object and its arguments array. | 786 // object, passing the non-closure object and its arguments array. |
789 // EDI: non-closure object. | 787 // EDI: non-closure object. |
790 // EDX: arguments descriptor array (num_args is first Smi element, closure | 788 // EDX: arguments descriptor array (num_args is first Smi element, closure |
791 // object is not included in num_args). | 789 // object is not included in num_args). |
792 | 790 |
793 // 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 |
794 // calling into the runtime. | 792 // calling into the runtime. |
795 __ EnterFrame(0); | 793 __ EnterFrame(0); |
796 | 794 |
797 // Setup space for return value on stack by pushing smi 0. | 795 __ pushl(raw_null); // Setup space on stack for result from error reporting. |
798 __ pushl(Immediate(0)); // Result from reporting the error. | |
799 __ pushl(EDI); // Non-closure object. | 796 __ pushl(EDI); // Non-closure object. |
800 // Total number of args is the first Smi in args descriptor array (EDX). | 797 // Total number of args is the first Smi in args descriptor array (EDX). |
801 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); // Load num_args. | 798 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); // Load num_args. |
802 __ SmiUntag(EDI); | 799 __ SmiUntag(EDI); |
803 // See stack layout below explaining "wordSize * 4" offset. | 800 // See stack layout below explaining "wordSize * 4" offset. |
804 PushArgumentsArray(assembler, (kWordSize * 4)); | 801 PushArgumentsArray(assembler, (kWordSize * 4)); |
805 | 802 |
806 // Stack: | 803 // Stack: |
807 // TOS + 0: Argument array. | 804 // TOS + 0: Argument array. |
808 // TOS + 1: Non-closure object. | 805 // TOS + 1: Non-closure object. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 } | 928 } |
932 | 929 |
933 | 930 |
934 // Called for inline allocation of contexts. | 931 // Called for inline allocation of contexts. |
935 // Input: | 932 // Input: |
936 // EDX: number of context variables. | 933 // EDX: number of context variables. |
937 // Output: | 934 // Output: |
938 // EAX: new allocated RawContext object. | 935 // EAX: new allocated RawContext object. |
939 // EBX and EDX are destroyed. | 936 // EBX and EDX are destroyed. |
940 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 937 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
| 938 const Immediate raw_null = |
| 939 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
941 if (FLAG_inline_alloc) { | 940 if (FLAG_inline_alloc) { |
942 const Class& context_class = Class::ZoneHandle(Object::context_class()); | 941 const Class& context_class = Class::ZoneHandle(Object::context_class()); |
943 Label slow_case; | 942 Label slow_case; |
944 Heap* heap = Isolate::Current()->heap(); | 943 Heap* heap = Isolate::Current()->heap(); |
945 // First compute the rounded instance size. | 944 // First compute the rounded instance size. |
946 // EDX: number of context variables. | 945 // EDX: number of context variables. |
947 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); | 946 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); |
948 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | 947 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); |
949 __ andl(EBX, Immediate(-kObjectAlignment)); | 948 __ andl(EBX, Immediate(-kObjectAlignment)); |
950 | 949 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 } | 1016 } |
1018 | 1017 |
1019 // Done allocating and initializing the context. | 1018 // Done allocating and initializing the context. |
1020 // EAX: new object. | 1019 // EAX: new object. |
1021 __ ret(); | 1020 __ ret(); |
1022 | 1021 |
1023 __ Bind(&slow_case); | 1022 __ Bind(&slow_case); |
1024 } | 1023 } |
1025 // Create a stub frame. | 1024 // Create a stub frame. |
1026 __ EnterFrame(0); | 1025 __ EnterFrame(0); |
1027 const Context& new_context = Context::ZoneHandle(); | 1026 __ pushl(raw_null); // Setup space on stack for return value. |
1028 __ PushObject(new_context); // Push Null context for return value. | |
1029 __ SmiTag(EDX); | 1027 __ SmiTag(EDX); |
1030 __ pushl(EDX); | 1028 __ pushl(EDX); |
1031 __ CallRuntimeFromStub(kAllocateContextRuntimeEntry); // Allocate context. | 1029 __ CallRuntimeFromStub(kAllocateContextRuntimeEntry); // Allocate context. |
1032 __ popl(EAX); // Pop number of context variables argument. | 1030 __ popl(EAX); // Pop number of context variables argument. |
1033 __ popl(EAX); // Pop the new context object. | 1031 __ popl(EAX); // Pop the new context object. |
1034 // EAX: new object | 1032 // EAX: new object |
1035 // Restore the frame pointer. | 1033 // Restore the frame pointer. |
1036 __ LeaveFrame(); | 1034 __ LeaveFrame(); |
1037 __ ret(); | 1035 __ ret(); |
1038 } | 1036 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 __ ret(); | 1196 __ ret(); |
1199 | 1197 |
1200 __ Bind(&slow_case); | 1198 __ Bind(&slow_case); |
1201 } | 1199 } |
1202 if (is_cls_parameterized) { | 1200 if (is_cls_parameterized) { |
1203 __ movl(EAX, Address(ESP, kObjectTypeArgumentsOffset)); | 1201 __ movl(EAX, Address(ESP, kObjectTypeArgumentsOffset)); |
1204 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); | 1202 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); |
1205 } | 1203 } |
1206 // Create a stub frame. | 1204 // Create a stub frame. |
1207 __ EnterFrame(0); | 1205 __ EnterFrame(0); |
1208 const Object& new_object = Object::ZoneHandle(); | 1206 __ pushl(raw_null); // Setup space on stack for return value. |
1209 __ PushObject(new_object); // Push Null object for return value. | |
1210 __ PushObject(cls); // Push class of object to be allocated. | 1207 __ PushObject(cls); // Push class of object to be allocated. |
1211 if (is_cls_parameterized) { | 1208 if (is_cls_parameterized) { |
1212 __ pushl(EAX); // Push type arguments of object to be allocated. | 1209 __ pushl(EAX); // Push type arguments of object to be allocated. |
1213 __ pushl(EDX); // Push type arguments of instantiator. | 1210 __ pushl(EDX); // Push type arguments of instantiator. |
1214 } else { | 1211 } else { |
1215 __ pushl(raw_null); // Push null type arguments. | 1212 __ pushl(raw_null); // Push null type arguments. |
1216 __ pushl(raw_null); // Push null instantiator. | 1213 __ pushl(raw_null); // Push null instantiator. |
1217 } | 1214 } |
1218 __ CallRuntimeFromStub(kAllocateObjectRuntimeEntry); // Allocate object. | 1215 __ CallRuntimeFromStub(kAllocateObjectRuntimeEntry); // Allocate object. |
1219 __ popl(EAX); // Pop argument (instantiator). | 1216 __ popl(EAX); // Pop argument (instantiator). |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 __ Bind(&slow_case); | 1344 __ Bind(&slow_case); |
1348 } | 1345 } |
1349 if (has_type_arguments) { | 1346 if (has_type_arguments) { |
1350 __ movl(ECX, Address(ESP, kTypeArgumentsOffset)); | 1347 __ movl(ECX, Address(ESP, kTypeArgumentsOffset)); |
1351 } | 1348 } |
1352 if (is_implicit_instance_closure) { | 1349 if (is_implicit_instance_closure) { |
1353 __ movl(EAX, Address(ESP, kReceiverOffset)); | 1350 __ movl(EAX, Address(ESP, kReceiverOffset)); |
1354 } | 1351 } |
1355 // Create a stub frame. | 1352 // Create a stub frame. |
1356 __ EnterFrame(0); | 1353 __ EnterFrame(0); |
1357 const Closure& new_closure = Closure::ZoneHandle(); | 1354 __ pushl(raw_null); // Setup space on stack for return value. |
1358 __ PushObject(new_closure); // Push Null closure for return value. | |
1359 __ PushObject(func); | 1355 __ PushObject(func); |
1360 if (is_implicit_static_closure) { | 1356 if (is_implicit_static_closure) { |
1361 __ CallRuntimeFromStub(kAllocateImplicitStaticClosureRuntimeEntry); | 1357 __ CallRuntimeFromStub(kAllocateImplicitStaticClosureRuntimeEntry); |
1362 } else { | 1358 } else { |
1363 if (is_implicit_instance_closure) { | 1359 if (is_implicit_instance_closure) { |
1364 __ pushl(EAX); // Receiver. | 1360 __ pushl(EAX); // Receiver. |
1365 } | 1361 } |
1366 if (has_type_arguments) { | 1362 if (has_type_arguments) { |
1367 __ pushl(ECX); // Push type arguments of closure to be allocated. | 1363 __ pushl(ECX); // Push type arguments of closure to be allocated. |
1368 } else { | 1364 } else { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1401 // The target function was not found, so invoke method | 1397 // The target function was not found, so invoke method |
1402 // "void noSuchMethod(function_name, Array arguments)". | 1398 // "void noSuchMethod(function_name, Array arguments)". |
1403 // TODO(regis): For now, we simply pass the actual arguments, both positional | 1399 // TODO(regis): For now, we simply pass the actual arguments, both positional |
1404 // and named, as the argument array. This is not correct if out-of-order | 1400 // and named, as the argument array. This is not correct if out-of-order |
1405 // named arguments were passed. | 1401 // named arguments were passed. |
1406 // The signature of the "noSuchMethod" method has to change from | 1402 // The signature of the "noSuchMethod" method has to change from |
1407 // noSuchMethod(String name, Array arguments) to something like | 1403 // noSuchMethod(String name, Array arguments) to something like |
1408 // noSuchMethod(InvocationMirror call). | 1404 // noSuchMethod(InvocationMirror call). |
1409 // Also, the class NoSuchMethodException has to be modified accordingly. | 1405 // Also, the class NoSuchMethodException has to be modified accordingly. |
1410 // Total number of args is the first Smi in args descriptor array (EDX). | 1406 // Total number of args is the first Smi in args descriptor array (EDX). |
| 1407 const Immediate raw_null = |
| 1408 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1411 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); | 1409 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); |
1412 __ SmiUntag(EDI); | 1410 __ SmiUntag(EDI); |
1413 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver. | 1411 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver. |
1414 | 1412 |
1415 __ EnterFrame(0); | 1413 __ EnterFrame(0); |
1416 // Setup space for return value on stack by pushing smi 0. | 1414 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. |
1417 __ pushl(Immediate(0)); // Result from noSuchMethod. | |
1418 __ pushl(EAX); // Receiver. | 1415 __ pushl(EAX); // Receiver. |
1419 __ pushl(ECX); // IC data array. | 1416 __ pushl(ECX); // IC data array. |
1420 __ pushl(EDX); // Arguments descriptor array. | 1417 __ pushl(EDX); // Arguments descriptor array. |
1421 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. | 1418 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. |
1422 // See stack layout below explaining "wordSize * 8" offset. | 1419 // See stack layout below explaining "wordSize * 8" offset. |
1423 PushArgumentsArray(assembler, (kWordSize * 8)); | 1420 PushArgumentsArray(assembler, (kWordSize * 8)); |
1424 | 1421 |
1425 // Stack: | 1422 // Stack: |
1426 // TOS + 0: Argument array. | 1423 // TOS + 0: Argument array. |
1427 // TOS + 1: Arguments descriptor array. | 1424 // TOS + 1: Arguments descriptor array. |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1525 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. | 1522 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. |
1526 __ cmpl(EDI, raw_null); // Done? | 1523 __ cmpl(EDI, raw_null); // Done? |
1527 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1524 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
1528 } | 1525 } |
1529 | 1526 |
1530 __ Bind(&ic_miss); | 1527 __ Bind(&ic_miss); |
1531 // Get receiver, again. | 1528 // Get receiver, again. |
1532 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1529 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
1533 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. | 1530 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. |
1534 __ EnterFrame(0); | 1531 __ EnterFrame(0); |
1535 // Setup space for return value on stack by pushing smi 0. | |
1536 __ pushl(EDX); // Preserve arguments array. | 1532 __ pushl(EDX); // Preserve arguments array. |
1537 __ pushl(ECX); // Preserve IC data array | 1533 __ pushl(ECX); // Preserve IC data array |
1538 __ pushl(Immediate(0)); // Space for result (target code object). | 1534 __ pushl(raw_null); // Setup space on stack for result (target code object). |
1539 __ movl(EDX, FieldAddress(EDX, Array::data_offset())); | 1535 __ movl(EDX, FieldAddress(EDX, Array::data_offset())); |
1540 // Push call arguments. | 1536 // Push call arguments. |
1541 for (intptr_t i = 0; i < num_args; i++) { | 1537 for (intptr_t i = 0; i < num_args; i++) { |
1542 __ movl(EDX, Address(EAX, -kWordSize * i)); | 1538 __ movl(EDX, Address(EAX, -kWordSize * i)); |
1543 __ pushl(EDX); | 1539 __ pushl(EDX); |
1544 } | 1540 } |
1545 if (num_args == 1) { | 1541 if (num_args == 1) { |
1546 __ CallRuntimeFromStub(kInlineCacheMissHandlerOneArgRuntimeEntry); | 1542 __ CallRuntimeFromStub(kInlineCacheMissHandlerOneArgRuntimeEntry); |
1547 } else if (num_args == 2) { | 1543 } else if (num_args == 2) { |
1548 __ CallRuntimeFromStub(kInlineCacheMissHandlerTwoArgsRuntimeEntry); | 1544 __ CallRuntimeFromStub(kInlineCacheMissHandlerTwoArgsRuntimeEntry); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1642 __ popl(EDX); | 1638 __ popl(EDX); |
1643 __ popl(ECX); | 1639 __ popl(ECX); |
1644 __ LeaveFrame(); | 1640 __ LeaveFrame(); |
1645 // Now call the dynamic function. | 1641 // Now call the dynamic function. |
1646 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); | 1642 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); |
1647 } | 1643 } |
1648 | 1644 |
1649 } // namespace dart | 1645 } // namespace dart |
1650 | 1646 |
1651 #endif // defined TARGET_ARCH_IA32 | 1647 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |