OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 __ movl(EAX, Address(EBX, 0)); | 389 __ movl(EAX, Address(EBX, 0)); |
390 __ movl(Address(ECX, 0), EAX); | 390 __ movl(Address(ECX, 0), EAX); |
391 __ AddImmediate(ECX, Immediate(kWordSize)); | 391 __ AddImmediate(ECX, Immediate(kWordSize)); |
392 __ AddImmediate(EBX, Immediate(-kWordSize)); | 392 __ AddImmediate(EBX, Immediate(-kWordSize)); |
393 __ Bind(&loop_condition); | 393 __ Bind(&loop_condition); |
394 __ decl(EDX); | 394 __ decl(EDX); |
395 __ j(POSITIVE, &loop, Assembler::kNearJump); | 395 __ j(POSITIVE, &loop, Assembler::kNearJump); |
396 } | 396 } |
397 | 397 |
398 | 398 |
399 // Input parameters: | |
400 // ECX: ic-data. | |
401 // EDX: arguments descriptor array. | |
402 // Note: The receiver object is the first argument to the function being | |
403 // called, the stub accesses the receiver from this location directly | |
404 // when trying to resolve the call. | |
405 // Uses EDI. | |
406 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | |
407 __ EnterStubFrame(); | |
408 | |
409 const Immediate& raw_null = | |
410 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
411 __ pushl(raw_null); // Space for the return value. | |
412 | |
413 // Push the receiver as an argument. Load the smi-tagged argument | |
414 // count into EDI to index the receiver in the stack. There are | |
415 // three words (null, stub's pc marker, saved fp) above the return | |
416 // address. | |
417 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | |
418 __ pushl(Address(ESP, EDI, TIMES_2, (3 * kWordSize))); | |
419 | |
420 __ pushl(ECX); // Pass IC data object. | |
421 __ pushl(EDX); // Pass arguments descriptor array. | |
422 | |
423 // Pass the call's arguments array. | |
424 __ movl(EDX, EDI); // Smi-tagged arguments array length. | |
425 PushArgumentsArray(assembler); | |
426 | |
427 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); | |
428 | |
429 // Remove arguments. | |
430 __ Drop(4); | |
431 __ popl(EAX); // Get result into EAX. | |
432 __ LeaveFrame(); | |
433 __ ret(); | |
434 } | |
435 | |
436 | |
437 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 399 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
438 intptr_t deopt_reason, | 400 intptr_t deopt_reason, |
439 uword saved_registers_address); | 401 uword saved_registers_address); |
440 | 402 |
441 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); | 403 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); |
442 | 404 |
443 | 405 |
444 // Used by eager and lazy deoptimization. Preserve result in EAX if necessary. | 406 // Used by eager and lazy deoptimization. Preserve result in EAX if necessary. |
445 // This stub translates optimized frame into unoptimized frame. The optimized | 407 // This stub translates optimized frame into unoptimized frame. The optimized |
446 // frame can contain values in registers and on stack, the unoptimized | 408 // frame can contain values in registers and on stack, the unoptimized |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); | 538 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); |
577 __ pushl(raw_null); // Space for the result of the runtime call. | 539 __ pushl(raw_null); // Space for the result of the runtime call. |
578 __ pushl(EAX); // Pass receiver. | 540 __ pushl(EAX); // Pass receiver. |
579 __ pushl(ECX); // Pass IC data. | 541 __ pushl(ECX); // Pass IC data. |
580 __ pushl(EDX); // Pass arguments descriptor. | 542 __ pushl(EDX); // Pass arguments descriptor. |
581 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 543 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
582 // Discard arguments. | 544 // Discard arguments. |
583 __ popl(EAX); | 545 __ popl(EAX); |
584 __ popl(EAX); | 546 __ popl(EAX); |
585 __ popl(EAX); | 547 __ popl(EAX); |
586 __ popl(EAX); // Return value from the runtime call (instructions). | 548 __ popl(EAX); // Return value from the runtime call (function). |
587 __ popl(EDX); // Restore arguments descriptor. | 549 __ popl(EDX); // Restore arguments descriptor. |
588 __ popl(ECX); // Restore IC data. | 550 __ popl(ECX); // Restore IC data. |
589 __ LeaveFrame(); | 551 __ LeaveFrame(); |
590 | 552 |
591 Label lookup; | 553 __ movl(EBX, FieldAddress(EAX, Function::code_offset())); |
592 __ cmpl(EAX, raw_null); | 554 __ movl(EBX, FieldAddress(EBX, Code::instructions_offset())); |
593 __ j(EQUAL, &lookup, Assembler::kNearJump); | 555 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
594 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 556 __ jmp(EBX); |
595 __ jmp(EAX); | |
596 | |
597 __ Bind(&lookup); | |
598 __ jmp(&StubCode::InstanceFunctionLookupLabel()); | |
599 } | 557 } |
600 | 558 |
601 | 559 |
602 // Called for inline allocation of arrays. | 560 // Called for inline allocation of arrays. |
603 // Input parameters: | 561 // Input parameters: |
604 // EDX : Array length as Smi. | 562 // EDX : Array length as Smi. |
605 // ECX : array element type (either NULL or an instantiated type). | 563 // ECX : array element type (either NULL or an instantiated type). |
606 // Uses EAX, EBX, ECX, EDI as temporary registers. | 564 // Uses EAX, EBX, ECX, EDI as temporary registers. |
607 // NOTE: EDX cannot be clobbered here as the caller relies on it being saved. | 565 // NOTE: EDX cannot be clobbered here as the caller relies on it being saved. |
608 // The newly allocated object is returned in EAX. | 566 // The newly allocated object is returned in EAX. |
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 for (intptr_t i = 0; i < num_args; i++) { | 1413 for (intptr_t i = 0; i < num_args; i++) { |
1456 __ movl(EBX, Address(EAX, -kWordSize * i)); | 1414 __ movl(EBX, Address(EAX, -kWordSize * i)); |
1457 __ pushl(EBX); | 1415 __ pushl(EBX); |
1458 } | 1416 } |
1459 __ pushl(ECX); // Pass IC data object. | 1417 __ pushl(ECX); // Pass IC data object. |
1460 __ CallRuntime(handle_ic_miss, num_args + 1); | 1418 __ CallRuntime(handle_ic_miss, num_args + 1); |
1461 // Remove the call arguments pushed earlier, including the IC data object. | 1419 // Remove the call arguments pushed earlier, including the IC data object. |
1462 for (intptr_t i = 0; i < num_args + 1; i++) { | 1420 for (intptr_t i = 0; i < num_args + 1; i++) { |
1463 __ popl(EAX); | 1421 __ popl(EAX); |
1464 } | 1422 } |
1465 __ popl(EAX); // Pop returned code object into EAX (null if not found). | 1423 __ popl(EAX); // Pop returned function object into EAX. |
1466 __ popl(ECX); // Restore IC data array. | 1424 __ popl(ECX); // Restore IC data array. |
1467 __ popl(EDX); // Restore arguments descriptor array. | 1425 __ popl(EDX); // Restore arguments descriptor array. |
1468 __ LeaveFrame(); | 1426 __ LeaveFrame(); |
1469 Label call_target_function; | 1427 Label call_target_function; |
1470 __ cmpl(EAX, raw_null); | 1428 __ jmp(&call_target_function); |
1471 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump); | |
1472 // NoSuchMethod or closure. | |
1473 // Mark IC call that it may be a closure call that does not collect | |
1474 // type feedback. | |
1475 __ movb(FieldAddress(ECX, ICData::is_closure_call_offset()), Immediate(1)); | |
1476 __ jmp(&StubCode::InstanceFunctionLookupLabel()); | |
1477 | 1429 |
1478 __ Bind(&found); | 1430 __ Bind(&found); |
1479 // EBX: Pointer to an IC data check group. | 1431 // EBX: Pointer to an IC data check group. |
1480 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; | 1432 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; |
1481 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; | 1433 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; |
1482 __ movl(EAX, Address(EBX, target_offset)); | 1434 __ movl(EAX, Address(EBX, target_offset)); |
1483 __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1))); | 1435 __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1))); |
1484 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); | 1436 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); |
1485 __ movl(Address(EBX, count_offset), | 1437 __ movl(Address(EBX, count_offset), |
1486 Immediate(Smi::RawValue(Smi::kMaxValue))); | 1438 Immediate(Smi::RawValue(Smi::kMaxValue))); |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1986 const Register temp = ECX; | 1938 const Register temp = ECX; |
1987 __ movl(left, Address(ESP, 2 * kWordSize)); | 1939 __ movl(left, Address(ESP, 2 * kWordSize)); |
1988 __ movl(right, Address(ESP, 1 * kWordSize)); | 1940 __ movl(right, Address(ESP, 1 * kWordSize)); |
1989 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1941 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1990 __ ret(); | 1942 __ ret(); |
1991 } | 1943 } |
1992 | 1944 |
1993 } // namespace dart | 1945 } // namespace dart |
1994 | 1946 |
1995 #endif // defined TARGET_ARCH_IA32 | 1947 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |